/*
 * CcExpr.c
 *
 *  Created on: 2012/04/28
 *      Author: guanxiaoying
 */
#include "../coredef.h"
#include "cc.h"

#define COMBINE_LEFT     1
#define COMBINE_RIGHT    2
static U4  gblDelimiter[] = {
		xLEX_SEMICOLON,
		xLEX_ENDOFFILE,
		xLEX_OPENBLOCK,
		xLEX_CLOSEBLOCK,
		xLEX_ELLIPSIS,
		xLEX_UNDEFINED
};
static  struct {
	PSZ  pszFuncMacro;
} stFuncMacro = {"__func__"};


static AST ccExpCast( VOID );
static AST ccExpParser( U4 *ulEndToken );
static BOOL ccExpSolveTypes( AST astRoot );
static S2 ccExpSetFlag( AST astRoot );
static AST ccExpCalcute( AST astRoot );
static U2 ccExpGetBinOpPriority( U2 op ){
	return (op>>8);
}
static U2 ccExpGetBinOpCombineRule( U2 op ){
	U2  pri1 = ccExpGetBinOpPriority( EXPR_CONDITION );
	U2  pri2 = ccExpGetBinOpPriority( EXPR_ASSIGN );
	U2  pri3 = ccExpGetBinOpPriority( op );
	if( pri3 == pri1 || pri3 == pri2 ){
		return COMBINE_RIGHT;
	}
	return COMBINE_LEFT;
}
static BOOL ccExprIsNullPointer( AST  astNode ){

	AST	astTypeInfo ;		/* 型情報			*/
	AST	astChdExp ;			/* 子演算式		*/
	AST	astValueInfo ;		/* 定数情報		*/
	U4	ulOperatorKind ;	/* 演算子種類		*/


	if( astNode == 0 ){
		return FALSE;
	}

	ulOperatorKind = stExpressionAccess.opKind.get( astNode ) ;
	while ( ulOperatorKind == EXPR_PARENTHESE ){
		astNode = stExpressionAccess.leftChild.get( astNode );
		ulOperatorKind = stExpressionAccess.opKind.get( astNode ) ;
	}
	if  ( ulOperatorKind == EXPR_CAST ){
		astChdExp = stExpressionAccess.leftChild.get( astNode );
		astTypeInfo = stExpressionAccess.type.get(astChdExp);
		if( ! CcTypeIsPointer( astTypeInfo ) ){
			return( FALSE ) ;
		}
		astTypeInfo = stTypeInfoAccess.elementType.get( astTypeInfo );
		astTypeInfo = CcTypeGetNoQualType( astTypeInfo );
		if( astTypeInfo != TYPE_VOID )	{
			return( FALSE ) ;
		}

		astChdExp = stExpressionAccess.rightChild.get( astNode );
	}
	else{
		astChdExp = astNode;
	}
	astValueInfo = stExpressionAccess.constValue.get( astChdExp );
	if( astValueInfo == 0 ){
		astValueInfo = ccExpCalcute(astChdExp);
	}
	if( astValueInfo == 0 ){
		return( FALSE ) ;
	}
	astTypeInfo = stValueInfoAccess.type.get( astValueInfo );
	if( ! CcTypeIsInteger( astTypeInfo ) ){
		return( FALSE ) ;
	}
	if( CcValueIsZero( astValueInfo )){
		return TRUE;
	}

	return( FALSE ) ;
}

static BOOL ccExpIsTerminalToken( AST astCurrToken , U4 *ulEndToken ){
	U4 currTokenKind;
	S4 nCnt;

	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	nCnt = 0 ;
	while( ulEndToken[nCnt] != xLEX_UNDEFINED ){
		if( currTokenKind == ulEndToken[nCnt] ){
			return TRUE;
		}
		nCnt++ ;
	}
	if( xLEXBIT_CTRL & currTokenKind ){
		return TRUE;
	}
	if( xLEXBIT_DEF & currTokenKind ){
		return TRUE;
	}
	nCnt = 0 ;
	while( gblDelimiter[nCnt] != xLEX_UNDEFINED ){
		if( currTokenKind == gblDelimiter[nCnt] ){
			return TRUE;
		}
		nCnt++ ;
	}
	return FALSE;
}
static U2 ccExpGetBinaryOpKind( U4 tokenKind ){
	U2 opKind = 0;
	switch( tokenKind ){
	case xLEX_MUL:{opKind = EXPR_MUL; break;}
	case xLEX_DIV:{opKind = EXPR_DIV; break;}
	case xLEX_MOD:{opKind = EXPR_MOD; break;}
	case xLEX_ADD:{opKind = EXPR_ADD; break;}
	case xLEX_SUB:{opKind = EXPR_SUB; break;}
	case xLEX_SHL:{opKind = EXPR_LEFTSHIFT; break;}
	case xLEX_SHR:{opKind = EXPR_RIGHTSHIFT; break;}
	case xLEX_GRTR:{opKind = EXPR_GREATER; break;}
	case xLEX_GRTREQU:{opKind = EXPR_GREATEREQU; break;}
	case xLEX_LESS:{opKind = EXPR_LESS; break;}
	case xLEX_LESSEQU:{opKind = EXPR_LESSEQU; break;}
	case xLEX_EQUEQU:{opKind = EXPR_EQUAL; break;}
	case xLEX_NOTEQU:{opKind = EXPR_UNEQUAL; break;}
	case xLEX_AND:{opKind = EXPR_BIT_AND; break;}
	case xLEX_XOR:{opKind = EXPR_BIT_EXOR; break;}
	case xLEX_OR:{opKind = EXPR_BIT_INOR; break;}

	case xLEX_LAND:{opKind = EXPR_LOGIC_AND; break;}
	case xLEX_LOR:{opKind = EXPR_LOGIC_OR; break;}

	case xLEX_QUESTION:{opKind = EXPR_CONDITION; break;}
	case xLEX_COLON:{opKind = EXPR_COLON; break;}

	case xLEX_EQU:{opKind = EXPR_ASSIGN; break;}
	case xLEX_ADDEQU:{opKind = EXPR_ADD_ASSIGN; break;}
	case xLEX_SUBEQU:{opKind = EXPR_SUB_ASSIGN; break;}
	case xLEX_MULEQU:{opKind = EXPR_MUL_ASSIGN; break;}
	case xLEX_DIVEQU:{opKind = EXPR_DIV_ASSIGN; break;}
	case xLEX_MODEQU:{opKind = EXPR_MOD_ASSIGN; break;}
	case xLEX_SHLEQU:{opKind = EXPR_LSHT_ASSIGN; break;}
	case xLEX_SHREQU:{opKind = EXPR_RSHT_ASSIGN; break;}
	case xLEX_ANDEQU:{opKind = EXPR_BITAND_ASSIGN; break;}
	case xLEX_OREQU:{opKind = EXPR_BITINOR_ASSIGN; break;}
	case xLEX_XOREQU:{opKind = EXPR_BITEXOR_ASSIGN; break;}
	case xLEX_COMMA:{opKind = EXPR_COMMA; break;}
	default:{opKind = 0; break;}
	}
	return opKind;
}
static AST ccExpTypeNameNode( VOID ){
	AST firstScp, secondScp;
	AST astCurrToken;
	U4  currTokenKind;
	AST astDeclaration;
	BOOL bIllegal=FALSE;
	AST astTypeExp=0;

	TRY;
	astCurrToken = CcLexGetCurrToken();
	firstScp = stLexTokenAccess.codeScp.get( astCurrToken );
	CcLexGetNextToken();
	astDeclaration = CcDeclaration( xNAMESPACE_TYPENAME );
	if( astDeclaration == 0 ){
		CcThrowWarning( CC_EXP_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
		return 0;
	}
	astCurrToken =  CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );

	if( currTokenKind != xLEX_CLOSEPAREN ){
		CcThrowWarning( CC_EXP_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
		bIllegal = TRUE;
	}else{
		CcLexGetNextToken();
	}
	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
	firstScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
	stExpressionAccess.alloc(1);
	astTypeExp = stExpressionAccess.getMax();
	stExpressionAccess.opKind.set( astTypeExp, EXPR_DECLARATION );
	stExpressionAccess.result_declaration.set( astTypeExp, astDeclaration );
	stExpressionAccess.bIllegal.set( astTypeExp, bIllegal );
	stExpressionAccess.codeScp.set(astTypeExp, firstScp);
	CATCH(astTypeExp);
	return astTypeExp;
}
static AST ccExpBuild( AST astLeft, U2 op, AST astRight ){
	U2  usPriority = ccExpGetBinOpPriority( op );
	U2  usCombinRule = ccExpGetBinOpCombineRule( op );
	U2  rootOp;
	U2  rootPriority;
	AST astFather=0;
	AST astResultExp;
	AST astNewExp;
	AST  firstScp;
	AST  secondScp;
	AST  astChild;

	stExpressionAccess.alloc(1);
	astNewExp = stExpressionAccess.getMax();
	stExpressionAccess.opKind.set( astNewExp, op );
	if( astLeft == 0 ){
		stExpressionAccess.bIllegal.set( astNewExp, TRUE );
		stExpressionAccess.leftChild.set( astNewExp, astLeft );
		stExpressionAccess.parentKind.set( astLeft, KIND_EXPRESSIONINFO );
		stExpressionAccess.parent_expression.set( astLeft, astNewExp );

		stExpressionAccess.rightChild.set( astNewExp, astRight );
		stExpressionAccess.parentKind.set( astRight, KIND_EXPRESSIONINFO );
		stExpressionAccess.parent_expression.set( astRight, astNewExp );
		secondScp = stExpressionAccess.codeScp.get( astRight );
		stExpressionAccess.codeScp.set( astNewExp, secondScp );
		return astNewExp;
	}
	if( op == EXPR_COLON ){
		astResultExp = astLeft;
		while( astLeft ){
			rootOp = stExpressionAccess.opKind.get( astLeft );
			if( rootOp == EXPR_CONDITION ){
				astChild = stExpressionAccess.rightChild.get( astLeft );
				if( EXPR_COLON == stExpressionAccess.opKind.get( astChild )){
					// op first. goto the leaf
					astFather = astLeft;
					astLeft = stExpressionAccess.rightChild.get( astLeft );
				}else{
					break;
				}
			}else{
				astLeft = stExpressionAccess.rightChild.get( astLeft );
			}
		}
		if( astLeft == 0 ){
			CcThrowWarning( CC_EXP_OP_ERROR,
					stExpressionAccess.codeScp.get( astRight ),
					":", NULL );
			astResultExp = astNewExp;
		}else{
			astChild = stExpressionAccess.rightChild.get( astLeft );
			stExpressionAccess.leftChild.set( astNewExp, astChild );
			stExpressionAccess.parentKind.set( astChild, KIND_EXPRESSIONINFO );
			stExpressionAccess.parent_expression.set( astChild, astNewExp );

			stExpressionAccess.rightChild.set( astNewExp, astRight );
			stExpressionAccess.parentKind.set( astRight, KIND_EXPRESSIONINFO );
			stExpressionAccess.parent_expression.set( astRight, astNewExp );

			stExpressionAccess.rightChild.set( astLeft, astNewExp );
			stExpressionAccess.parentKind.set( astNewExp, KIND_EXPRESSIONINFO );
			stExpressionAccess.parent_expression.set( astNewExp, astLeft );
			firstScp = stExpressionAccess.codeScp.get( astLeft );
			secondScp = stExpressionAccess.codeScp.get( astRight );
			if(firstScp >= MIN_ARRAY && secondScp >= MIN_ARRAY  ){
				secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
			}
			stExpressionAccess.codeScp.set( astNewExp, secondScp );
		}
		return astResultExp;
	}
	astResultExp = astLeft;
	while( astLeft ){
		rootOp = stExpressionAccess.opKind.get( astLeft );
		if( rootOp == EXPR_CONDITION ){
			astChild = stExpressionAccess.rightChild.get( astLeft );
			if( EXPR_COLON != stExpressionAccess.opKind.get( astChild )){
				// op first. goto the leaf
				astFather = astLeft;
				astLeft = stExpressionAccess.rightChild.get( astLeft );
				continue;
			}
		}
		rootPriority = ccExpGetBinOpPriority( rootOp );
		if( rootPriority > usPriority ){
			// op first. goto the leaf
			astFather = astLeft;
			astLeft = stExpressionAccess.rightChild.get( astLeft );
		}else if( rootPriority < usPriority ){
			break;
		}else{
			if( usCombinRule == COMBINE_LEFT ){
				break;
			}else{
				// op first. goto the leaf
				astFather = astLeft;
				astLeft = stExpressionAccess.rightChild.get( astLeft );
			}
		}
	}
	// root first. rotate tree
	if( astFather == 0 ){
		astResultExp = astNewExp;
	}else{
		stExpressionAccess.rightChild.set( astFather, astNewExp );
		stExpressionAccess.parentKind.set( astNewExp, KIND_EXPRESSIONINFO );
		stExpressionAccess.parent_expression.set( astNewExp, astFather );
	}
	stExpressionAccess.leftChild.set( astNewExp, astLeft );
	stExpressionAccess.parentKind.set( astLeft, KIND_EXPRESSIONINFO );
	stExpressionAccess.parent_expression.set( astLeft, astNewExp );
	stExpressionAccess.rightChild.set( astNewExp, astRight );
	stExpressionAccess.parentKind.set( astRight, KIND_EXPRESSIONINFO );
	stExpressionAccess.parent_expression.set( astRight, astNewExp );
	firstScp = stExpressionAccess.codeScp.get( astLeft );
	secondScp = stExpressionAccess.codeScp.get( astRight );
	if(firstScp >= MIN_ARRAY && secondScp >= MIN_ARRAY  ){
		secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
	}

	stExpressionAccess.codeScp.set( astNewExp, secondScp );
	return astResultExp;
}
static AST ccExpInitialExpList( VOID ){
	AST astCompoundList;
	AST astInitList;
	stExpressionAccess.alloc(1);
	astCompoundList = stExpressionAccess.getMax();
	astInitList = CcInitializerMain();
	stExpressionAccess.opKind.set( astCompoundList, EXPR_INITEXPRLIST );
	stExpressionAccess.result_exprlist.set( astCompoundList, astInitList );
	stExpressionAccess.codeScp.set(astCompoundList,
			stExpressionListAccess.codeScp.get( astInitList ));
	return astCompoundList;
}
static BOOL ccExpCheckInitExpType( AST astLeftType, AST astRight ){
	AST astInitList;
	astInitList = stExpressionAccess.result_exprlist.get( astRight );
	CcInitializerCheck( astLeftType, astInitList );
	return TRUE;
}
static AST ccExpPrimary(VOID){
	AST  astCurrToken;
	AST  astPrimaryExp=0;
	AST  astResult;
	U4   currTokenKind;
	AST  firstScp;
	AST  secondScp;
	U4    ulEndToken[2];

	TRY;
	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );

	switch( currTokenKind ){
	case xLEX_SYMBOL:{
			AST  astFunc = CcStmtGetCurrFunction();
			PSZ  pszFuncName;
			AST  astType;
			if( astFunc >= MIN_ARRAY ){
				if ( strcmp( stLexTokenAccess.name.get( astCurrToken ), stFuncMacro .pszFuncMacro) == 0  ){
					pszFuncName = stSymbolInfoAccess.name.get( astFunc );
					stExpressionAccess.alloc(1);
					astPrimaryExp = stExpressionAccess.getMax();
					stExpressionAccess.opKind.set( astPrimaryExp, EXPR_STRING );
					stExpressionAccess.result_value.set( astPrimaryExp,
							stCcConstStringAccess.addStr( pszFuncName, strlen( pszFuncName ) ) );
					astType = TYPE_CHAR;
					astType = CcTypeAddArray(astType, strlen( pszFuncName ) + 1 );
					stExpressionAccess.type.set( astPrimaryExp, astType );
					stExpressionAccess.codeScp.set( astPrimaryExp, stLexTokenAccess.codeScp.get( astCurrToken ));
					astCurrToken = CcLexGetNextToken();
					break;
				}
			}

			astResult = CcBlockFindSymbol( stLexTokenAccess.name.get( astCurrToken ), NULL );
			if( astResult == 0 ){
				astResult = CcSymNewUnknown( stLexTokenAccess.name.get( astCurrToken ) );
				stSymbolInfoAccess.nameSpace.set( astResult, xNAMESPACE_ORD );
				stSymbolInfoAccess.codeScp.set(astResult,stLexTokenAccess.codeScp.get( astCurrToken ));
			}
			stSymbolInfoAccess.referred.set( astResult, TRUE );
			stExpressionAccess.alloc(1);
			astPrimaryExp = stExpressionAccess.getMax();
			stExpressionAccess.opKind.set( astPrimaryExp, EXPR_IDENTIFIER );
			stExpressionAccess.result_symbol.set( astPrimaryExp, astResult );
			stExpressionAccess.codeScp.set( astPrimaryExp, stLexTokenAccess.codeScp.get( astCurrToken ));
			astCurrToken = CcLexGetNextToken();
			break;
		}
	case xLEX_CONSTVALUE:
		astResult = stLexTokenAccess.paramIdx.get( astCurrToken );
		stExpressionAccess.alloc(1);
		astPrimaryExp = stExpressionAccess.getMax();
		stExpressionAccess.opKind.set( astPrimaryExp, EXPR_CONSTANT );
		stExpressionAccess.result_value.set( astPrimaryExp, astResult );
		stExpressionAccess.type.set( astPrimaryExp, stLexTokenAccess.type.get( astCurrToken ) );
		stExpressionAccess.codeScp.set( astPrimaryExp, stLexTokenAccess.codeScp.get( astCurrToken ));
		astCurrToken = CcLexGetNextToken();
		break;
	case xLEX_CONSTSTR:
		astResult = stLexTokenAccess.paramIdx.get( astCurrToken );
		stExpressionAccess.alloc(1);
		astPrimaryExp = stExpressionAccess.getMax();
		stExpressionAccess.opKind.set( astPrimaryExp, EXPR_STRING );
		stExpressionAccess.result_constStr.set( astPrimaryExp, astResult );
		stExpressionAccess.type.set( astPrimaryExp, stLexTokenAccess.type.get( astCurrToken ) );
		stExpressionAccess.codeScp.set( astPrimaryExp, stLexTokenAccess.codeScp.get( astCurrToken ));
		astCurrToken = CcLexGetNextToken();
		break;
	case xLEX_OPENPAREN:
		firstScp = stLexTokenAccess.codeScp.get( astCurrToken );
		astCurrToken = CcLexGetNextToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		if( currTokenKind == xLEX_OPENBLOCK ){
			stExpressionAccess.alloc(1);
			astPrimaryExp = stExpressionAccess.getMax();
			stExpressionAccess.opKind.set( astPrimaryExp, EXPR_STATEMENT );
			astResult = CcStmtBlockInExp( KIND_EXPRESSIONINFO, astPrimaryExp );
			stExpressionAccess.result_statement.set( astPrimaryExp, astResult );
			astCurrToken = CcLexGetCurrToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			if( currTokenKind != xLEX_CLOSEPAREN ){
				CcThrowWarning( CC_EXP_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
			}else{
				astCurrToken = CcLexGetNextToken();
			}
			secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
			secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
			stExpressionAccess.codeScp.set( astPrimaryExp, secondScp );
		}else{
			ulEndToken[0] = xLEX_CLOSEPAREN;
			ulEndToken[1] = xLEX_UNDEFINED;
			astResult = ccExpParser( ulEndToken );
			astCurrToken = CcLexGetCurrToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			if( astResult == 0 ){
				CcThrowWarning( CC_EXP_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
			}
			if( currTokenKind != xLEX_CLOSEPAREN ){
				CcThrowWarning( CC_EXP_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
			}else{
				astCurrToken = CcLexGetNextToken();
			}
			stExpressionAccess.alloc(1);
			astPrimaryExp = stExpressionAccess.getMax();
			stExpressionAccess.opKind.set( astPrimaryExp, EXPR_PARENTHESE );
			if( astResult ){
				stExpressionAccess.leftChild.set( astPrimaryExp, astResult );
				stExpressionAccess.parentKind.set( astResult, KIND_EXPRESSIONINFO );
				stExpressionAccess.parent_expression.set( astResult, astPrimaryExp );
			}else{
				stExpressionAccess.bIllegal.set( astPrimaryExp, TRUE );
			}
			secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
			secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
			stExpressionAccess.codeScp.set( astPrimaryExp, secondScp );
		}
		break;
	default:
		CcThrowWarning( CC_EXP_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
		astPrimaryExp = 0;
		break;
	}
	CATCH(astPrimaryExp);
	return astPrimaryExp;
}
static AST ccExpPostfix(VOID){
	AST  astCurrToken;
	AST  astPostfixExp=0;
	AST  astPrimaryExp=0;
	AST  astRight;
	AST  astTypeExp;
	U2   opKind;
	U4   currTokenKind;
	AST  firstScp;
	AST  secondScp;
	BOOL  bIllegal = FALSE;
	U4    ulEndToken[2];
	TRY;
	/*
	 * postfix-expression:
	 * 		Primary-expression
	 * 		postfix-expressio[]
	 * 		postfix-expressio()
	 * 		postfix-expressio.identifier
	 * 		postfix-expressio->identifier
	 * 		postfix-expressio++
	 * 		postfix-expressio--
	 * 		(typename){}
	 * unary-operator: one of
	 * 		& * + - ~ !
	 */
	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	firstScp = stLexTokenAccess.codeScp.get( astCurrToken );

	if( currTokenKind == xLEX_OPENPAREN ){
		astCurrToken = CcLexGetRT(1);
		if( CcDeclChkType( astCurrToken ) ){
			TRY;
			firstScp = stLexTokenAccess.codeScp.get( CcLexGetCurrToken() );
			astTypeExp = ccExpTypeNameNode();

			astCurrToken = CcLexGetCurrToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );

			if( currTokenKind == xLEX_OPENBLOCK ){
				astPrimaryExp = ccExpInitialExpList();
			}else{
				astPrimaryExp = 0;
			}
			astCurrToken = CcLexGetCurrToken();
			stExpressionAccess.alloc(1);
			astPostfixExp = stExpressionAccess.getMax();

			stExpressionAccess.opKind.set( astPostfixExp, EXPR_COMPOUNDLITERALS );
			stExpressionAccess.leftChild.set( astPostfixExp, astTypeExp );
			stExpressionAccess.parentKind.set( astTypeExp, KIND_EXPRESSIONINFO );
			stExpressionAccess.parent_expression.set( astTypeExp, astPostfixExp );
			if( astPrimaryExp == 0 ){
				astCurrToken = CcLexGetCurrToken();
				CcThrowWarning( CC_EXP_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
				stExpressionAccess.bIllegal.set( astPostfixExp, TRUE );
			}else{
				stExpressionAccess.rightChild.set( astPostfixExp, astPrimaryExp );
				stExpressionAccess.parentKind.set( astPrimaryExp, KIND_EXPRESSIONINFO );
				stExpressionAccess.parent_expression.set( astPrimaryExp, astPostfixExp );
			}
			secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
			firstScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
			stExpressionAccess.codeScp.set( astPostfixExp, firstScp );
			CATCH( astPostfixExp );
			astPrimaryExp = astPostfixExp;
		}else{
			astPrimaryExp = ccExpPrimary();
		}
	}else{
		astPrimaryExp = ccExpPrimary();
	}
	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	while( 1 ){
		switch(currTokenKind){
		case xLEX_OPENARRAY:
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			ulEndToken[0] = xLEX_CLOSEARRAY;
			ulEndToken[1] = xLEX_UNDEFINED;
			astRight = ccExpParser(ulEndToken);
			astCurrToken = CcLexGetCurrToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			if( astRight == 0 ){
				CcThrowWarning( CC_EXP_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
				bIllegal = TRUE;
			}
			if( currTokenKind != xLEX_CLOSEARRAY ){
				CcThrowWarning( CC_EXP_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
			}else{
				astCurrToken = CcLexGetNextToken();
				currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			}
			opKind = EXPR_ARRAY;
			break;
		case xLEX_OPENPAREN:
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			ulEndToken[0] = xLEX_CLOSEPAREN;
			ulEndToken[1] = xLEX_UNDEFINED;
			astRight = ccExpParser(ulEndToken);

			astCurrToken = CcLexGetCurrToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			if( currTokenKind != xLEX_CLOSEPAREN ){
				CcThrowWarning( CC_EXP_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
			}else{
				astCurrToken = CcLexGetNextToken();
				currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			}
			opKind = EXPR_FUNCTIONCALL;
			break;
		case xLEX_INC:
			opKind = EXPR_POSTINC;
			astRight=0;
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		case xLEX_DEC:
			opKind = EXPR_POSTDEC;
			astRight=0;
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		case xLEX_MEMREF:
			opKind = EXPR_MEMBER;
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			if( currTokenKind == xLEX_SYMBOL ){
				stExpressionAccess.alloc(1);
				astRight = stExpressionAccess.getMax();
				stExpressionAccess.opKind.set( astRight, EXPR_TOKEN );
				stExpressionAccess.result_temp_token.set( astRight, astCurrToken );
				stExpressionAccess.codeScp.set( astRight, stLexTokenAccess.codeScp.get(astCurrToken ));
				astCurrToken = CcLexGetNextToken();
				currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			}else{
				astRight = 0;
				bIllegal = TRUE;
				CcThrowWarning( CC_EXP_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
			}
			break;
		case xLEX_MEMREFP:
			opKind = EXPR_PTRMEMBER;
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			if( currTokenKind == xLEX_SYMBOL ){
				stExpressionAccess.alloc(1);
				astRight = stExpressionAccess.getMax();
				stExpressionAccess.opKind.set( astRight, EXPR_TOKEN );
				stExpressionAccess.result_temp_token.set( astRight, astCurrToken );
				stExpressionAccess.codeScp.set( astRight, stLexTokenAccess.codeScp.get(astCurrToken ));
				astCurrToken = CcLexGetNextToken();
				currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			}else{
				astRight = 0;
				bIllegal = TRUE;
				CcThrowWarning( CC_EXP_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
			}
			break;
		default:
			opKind = 0;
			astRight = 0;
			break;
		}
		if(opKind==0){
			break;
		}
		stExpressionAccess.alloc(1);
		astPostfixExp = stExpressionAccess.getMax();
		stExpressionAccess.opKind.set( astPostfixExp, opKind );
		stExpressionAccess.bIllegal.set( astPostfixExp, bIllegal );
		if( astPrimaryExp > 0 ){
			stExpressionAccess.leftChild.set( astPostfixExp, astPrimaryExp );
			stExpressionAccess.parentKind.set( astPrimaryExp, KIND_EXPRESSIONINFO );
			stExpressionAccess.parent_expression.set( astPrimaryExp, astPostfixExp );
		}else{
			stExpressionAccess.bIllegal.set( astPostfixExp, TRUE );
		}

		if( astRight ){
			stExpressionAccess.rightChild.set( astPostfixExp, astRight );
			stExpressionAccess.parentKind.set( astRight, KIND_EXPRESSIONINFO );
			stExpressionAccess.parent_expression.set( astRight, astPostfixExp );
		}
		secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
		firstScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
		stExpressionAccess.codeScp.set( astPostfixExp, firstScp );
		astPrimaryExp = astPostfixExp;
	}
	CATCH(astPrimaryExp);
	return astPrimaryExp;
}
static AST ccExpUnary( VOID ){
	AST  astCurrToken;
	AST  astPostfixExp;
	AST  astUnaryExp=0;
	U2   opKind=0;
	U4   currTokenKind;
	AST  firstScp;
	AST  secondScp;

	TRY;
	/*
	 * unary-expression:
	 * 		postfix-expression
	 * 		++ unary-expression
	 * 		-- unary-expression
	 * 		unary-operator cast-expression
	 * 		sizeof unary-expression
	 * 		sizeof ( type-name )
	 * unary-operator: one of
	 * 		& * + - ~ !
	 */
	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	firstScp = stLexTokenAccess.codeScp.get( astCurrToken );
	switch(currTokenKind){
	case xLEX_MUL:
		astCurrToken = CcLexGetNextToken();
		astUnaryExp = ccExpCast();
		opKind = EXPR_ASTERISK;
		break;
	case xLEX_AND:
		astCurrToken = CcLexGetNextToken();
		astUnaryExp = ccExpCast();
		opKind = EXPR_ADDRESS;
		break;
	case xLEX_SUB:
		astCurrToken = CcLexGetNextToken();
		astUnaryExp = ccExpCast();
		opKind = EXPR_MINUS;
		break;
	case xLEX_ADD:
		astCurrToken = CcLexGetNextToken();
		astUnaryExp = ccExpCast();
		opKind = EXPR_PLUS;
		break;
	case xLEX_NEG:
		astCurrToken = CcLexGetNextToken();
		astUnaryExp = ccExpCast();
		opKind = EXPR_BIT_NEGATION;
		break;
	case xLEX_NOT:
		astCurrToken = CcLexGetNextToken();
		astUnaryExp = ccExpCast();
		opKind = EXPR_NEGATION;
		break;
	case xLEX_INC:
		astCurrToken = CcLexGetNextToken();
		astUnaryExp = ccExpUnary();
		opKind = EXPR_PREINC;
		break;
	case xLEX_DEC:
		astCurrToken = CcLexGetNextToken();
		astUnaryExp = ccExpUnary();
		opKind = EXPR_PREDEC;
		break;
	case xLEX_SIZEOF:
		astCurrToken = CcLexGetNextToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		/*debug,13/1/17,S*/
		opKind = EXPR_SIZEOF;
		/*debug,13/1/17,E*/
		if( currTokenKind == xLEX_OPENPAREN ){
			astCurrToken = CcLexGetRT(1);
			if( CcDeclChkType ( astCurrToken ) ){
				astUnaryExp = ccExpTypeNameNode();
				break;
			}
		}
		astUnaryExp = ccExpUnary();
		/*debug,13/1/17,S*/
		//opKind = EXPR_SIZEOF;
		/*debug,13/1/17,E*/
		break;
	default:
		opKind = 0;
		astUnaryExp = ccExpPostfix();
		break;
	}
	if( opKind != 0 ){
		astPostfixExp = astUnaryExp;
		stExpressionAccess.alloc(1);
		astUnaryExp = stExpressionAccess.getMax();
		stExpressionAccess.opKind.set( astUnaryExp, opKind );
		if( astPostfixExp != 0 ){
			stExpressionAccess.leftChild.set(astUnaryExp, astPostfixExp);
			stExpressionAccess.parentKind.set( astPostfixExp, KIND_EXPRESSIONINFO );
			stExpressionAccess.parent_expression.set( astPostfixExp, astUnaryExp );
		}else{
			stExpressionAccess.bIllegal.set( astUnaryExp, TRUE );
			astCurrToken = CcLexGetCurrToken();
			CcThrowWarning( CC_EXP_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
		}
	}
	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
	firstScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
	stExpressionAccess.codeScp.set( astUnaryExp, firstScp );
	CATCH(astUnaryExp);
	return astUnaryExp;
}
static AST ccExpCast( VOID ){
	AST  astCurrToken;
	AST  astCastExp = 0;
	AST  astTypeExp;
	AST  astUnaryExp;
	U4   currTokenKind;
	U2   opKind;
	AST  firstScp;
	AST  secondScp;

	/*
	 * (type name) cast-expression
	 * (type name) { initial-expression-list }
	 */
	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind == xLEX_OPENPAREN ){
		astCurrToken = CcLexGetRT(1);
		if( CcDeclChkType( astCurrToken ) ){
			TRY;
			firstScp = stLexTokenAccess.codeScp.get( CcLexGetCurrToken() );

			astTypeExp = ccExpTypeNameNode();

			astCurrToken = CcLexGetCurrToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );

			if( currTokenKind == xLEX_OPENBLOCK ){
				astUnaryExp = ccExpInitialExpList();
				opKind = EXPR_COMPOUNDLITERALS;
			}else{
				astUnaryExp = ccExpCast();
				opKind = EXPR_CAST;
			}

			stExpressionAccess.alloc(1);
			astCastExp = stExpressionAccess.getMax();

			stExpressionAccess.opKind.set( astCastExp, opKind );
			stExpressionAccess.leftChild.set( astCastExp, astTypeExp );
			stExpressionAccess.parentKind.set( astTypeExp, KIND_EXPRESSIONINFO );
			stExpressionAccess.parent_expression.set( astTypeExp, astCastExp );
			if( astUnaryExp == 0 ){
				astCurrToken = CcLexGetCurrToken();
				CcThrowWarning( CC_EXP_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
				stExpressionAccess.bIllegal.set( astCastExp, TRUE );
			}else{
				stExpressionAccess.rightChild.set( astCastExp, astUnaryExp );
				stExpressionAccess.parentKind.set( astUnaryExp, KIND_EXPRESSIONINFO );
				stExpressionAccess.parent_expression.set( astUnaryExp, astCastExp );
			}
			secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
			firstScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
			stExpressionAccess.codeScp.set( astCastExp, firstScp );
			CATCH( astCastExp );
			return astCastExp;
		}
	}
	return ccExpUnary();
}
static AST ccExpParser( U4 *ulEndToken ){
	AST  astCurrToken;
	U4   currTokenKind;
	U2   opKind;
	AST  astLeftExp = 0;
	AST  astRightExp = 0;

	astCurrToken = CcLexGetCurrToken();
	if( ccExpIsTerminalToken( astCurrToken, ulEndToken ) ){
		return 0;
	}
	TRY;
	astLeftExp = ccExpCast() ;
	while( astLeftExp ){
		astCurrToken = CcLexGetCurrToken();
		if( ccExpIsTerminalToken( astCurrToken, ulEndToken ) ){
			break;
		}
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		opKind = ccExpGetBinaryOpKind( currTokenKind );
		if( opKind == 0 ){
			break;
		}
		astCurrToken = CcLexGetNextToken();
		astRightExp = ccExpCast() ;
		if( astRightExp == 0 ){
			astCurrToken = CcLexGetCurrToken();
			CcThrowWarning( CC_EXP_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
			break;
		}
		astLeftExp = ccExpBuild( astLeftExp, opKind, astRightExp );
	}
	CATCH(astLeftExp);
	return( astLeftExp ) ;
}
static BOOL ccExpCheckTree( AST astRoot ){
	AST astLeftChild;
	AST astRightChild;
	U2  op;
	BOOL bIllegal = FALSE;

	if (stExpressionAccess.bIllegal.get(astRoot)) {
		return TRUE;
	}
	op = stExpressionAccess.opKind.get(astRoot);
	switch (op) {
	case EXPR_TOKEN:
		if( stExpressionAccess.result_symbol.get( astRoot ) == 0 ){
			bIllegal = TRUE;
		}
		break;
	case EXPR_IDENTIFIER:
		if( stExpressionAccess.result_symbol.get( astRoot ) == 0 ){
			bIllegal = TRUE;
		}
		break;
	case EXPR_CONSTANT:
		if( stExpressionAccess.result_value.get( astRoot ) == 0 ){
			bIllegal = TRUE;
		}
		break;
	case EXPR_STRING:
		if( stExpressionAccess.result_constStr.get( astRoot ) == 0 ){
			bIllegal = TRUE;
		}
		break;
	case EXPR_DECLARATION:
		if( stExpressionAccess.result_declaration.get( astRoot ) == 0 ){
			bIllegal = TRUE;
		}
		break;
	case EXPR_STATEMENT:
		if( stExpressionAccess.result_statement.get( astRoot ) == 0 ){
			bIllegal = TRUE;
		}
		break;
	case EXPR_INITEXPRLIST:
		if( stExpressionAccess.result_exprlist.get( astRoot ) == 0 ){
			bIllegal = TRUE;
		}
		break;
	case EXPR_PARENTHESE:
		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		if( astLeftChild == 0 ){
			bIllegal = TRUE;
		}else{
			bIllegal = ccExpCheckTree( astLeftChild );
		}
		break;
	case EXPR_ARRAY:
	case EXPR_MEMBER:
	case EXPR_PTRMEMBER:
		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		astRightChild = stExpressionAccess.rightChild.get( astRoot );
		if( astLeftChild == 0 || astRightChild == 0  ){
			bIllegal = TRUE;
		}else{
			bIllegal = ccExpCheckTree( astLeftChild );
		}
		break;
	case EXPR_FUNCTIONCALL:
		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		if( astLeftChild == 0  ){
			bIllegal = TRUE;
		}else{
			bIllegal = ccExpCheckTree( astLeftChild );
		}
		break;

	case EXPR_POSTINC:
	case EXPR_POSTDEC:
		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		if( astLeftChild == 0  ){
			bIllegal = TRUE;
		}else{
			bIllegal = ccExpCheckTree( astLeftChild );
		}
		break;
	case EXPR_COMPOUNDLITERALS:
		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		astRightChild = stExpressionAccess.rightChild.get( astRoot );
		if( astLeftChild == 0 || astRightChild == 0  ){
			bIllegal = TRUE;
		}else{
			bIllegal = ccExpCheckTree( astLeftChild ) || ccExpCheckTree( astRightChild );
		}
		break;
	case EXPR_PREINC:
	case EXPR_PREDEC:
	case EXPR_ADDRESS:
	case EXPR_ASTERISK:
	case EXPR_PLUS:
	case EXPR_MINUS:
	case EXPR_NEGATION:
	case EXPR_BIT_NEGATION:
	case EXPR_SIZEOF:
		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		if( astLeftChild == 0  ){
			bIllegal = TRUE;
		}else{
			bIllegal = ccExpCheckTree( astLeftChild );
		}
		break;
	case EXPR_CAST:
	case EXPR_MUL:
	case EXPR_DIV:
	case EXPR_MOD:

	case EXPR_ADD:
	case EXPR_SUB:
	case EXPR_LEFTSHIFT:
	case EXPR_RIGHTSHIFT:

	case EXPR_GREATER:
	case EXPR_GREATEREQU:
	case EXPR_LESS:
	case EXPR_LESSEQU:

	case EXPR_EQUAL:
	case EXPR_UNEQUAL:

	case EXPR_BIT_AND:

	case EXPR_BIT_EXOR:

	case EXPR_BIT_INOR:

	case EXPR_LOGIC_AND:
	case EXPR_LOGIC_OR:


	case EXPR_ASSIGN:
	case EXPR_MUL_ASSIGN:
	case EXPR_DIV_ASSIGN:
	case EXPR_MOD_ASSIGN:
	case EXPR_ADD_ASSIGN:
	case EXPR_SUB_ASSIGN:
	case EXPR_LSHT_ASSIGN:
	case EXPR_RSHT_ASSIGN:
	case EXPR_BITAND_ASSIGN:
	case EXPR_BITEXOR_ASSIGN:
	case EXPR_BITINOR_ASSIGN:
		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		astRightChild = stExpressionAccess.rightChild.get( astRoot );
		if( astLeftChild == 0 || astRightChild == 0  ){
			bIllegal = TRUE;
		}else{
			bIllegal = ccExpCheckTree( astLeftChild ) || ccExpCheckTree( astRightChild );
		}
		break;
	case EXPR_CONDITION:
		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		astRightChild = stExpressionAccess.rightChild.get( astRoot );
		if( astLeftChild == 0 || astRightChild == 0  ){
			bIllegal = TRUE;
		}else{
			if( EXPR_COLON != stExpressionAccess.opKind.get(astRightChild) ){
				bIllegal = TRUE;
			}else{
				bIllegal = ccExpCheckTree( astLeftChild ) || ccExpCheckTree( astRightChild );
			}
		}
		break;
	case EXPR_COLON:
		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		astRightChild = stExpressionAccess.rightChild.get( astRoot );
		if( astLeftChild == 0 || astRightChild == 0  ){
			bIllegal = TRUE;
		}else{
			astRightChild = stExpressionAccess.parent_expression.get( astRoot );
			if( EXPR_CONDITION != stExpressionAccess.opKind.get(astRightChild) ){
				bIllegal = TRUE;
			}else{
				astRightChild = stExpressionAccess.rightChild.get( astRoot );
				bIllegal = ccExpCheckTree( astLeftChild ) || ccExpCheckTree( astRightChild );
			}
		}
		break;
	case EXPR_COMMA:
	case EXPR_ARG:
		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		astRightChild = stExpressionAccess.rightChild.get( astRoot );
		if( astLeftChild == 0 || astRightChild == 0  ){
			bIllegal = TRUE;
		}else{
			bIllegal = ccExpCheckTree( astRightChild );
		}
		break;
	}
	stExpressionAccess.bIllegal.set( astRoot, bIllegal );
	return bIllegal;
}
static AST ccExpConvertFunc_Array( AST astType ){
	if( CcTypeIsArray( astType ) ){
		astType = stTypeInfoAccess.elementType.get( astType );
		astType = CcTypeAddPointer( astType, 0, TYPEQUAL_CONST );
	}else if( CcTypeIsFunction( astType )  ){
		astType = CcTypeAddPointer( astType, 0, TYPEQUAL_CONST );
	}
	return astType;
}

static AST ccExpGetStUnMember( AST astType, AST astRightChild ){
	AST astChain=0;
	AST astSym=0;
	PSZ pszName_def;
	PSZ pszName;
	AST astToken;
	if( EXPR_TOKEN != stExpressionAccess.opKind.get( astRightChild ) ){
		return 0;
	}
	astToken = stExpressionAccess.result_temp_token.get( astRightChild );
	pszName = stLexTokenAccess.name.get( astToken );

	if( pszName == NULL ){
		return 0;
	}
	if( CcTypeIsUnion ( astType ) || CcTypeIsStruct( astType ) ){
		astChain = stTypeInfoAccess.memChain.get( astType ) ;
		while( astChain ){
			astSym = stUniteChainAccess.parameter_sym.get( astChain );
			if( astSym > 0 ){
				pszName_def = stSymbolInfoAccess.name.get( astSym );
				if( pszName_def != NULL && 0 == strcmp( pszName_def, pszName )){
					break;
				}
			}
			astChain = stUniteChainAccess.next.get( astChain );
		}
	}
	return astSym;
}
static BOOL ccExpGetModifiableFlg( AST astType ){
	if( CcTypeIsConst( astType ) || CcTypeIsArray( astType ) || CcTypeIsFunction( astType )){
		return FALSE;
	}
	return TRUE;
}
static BOOL ccExpIsModifiable( AST astExp ){
	AST astType;
	if( stExpressionAccess.bModifiabe.get( astExp ) == FALSE ){
		return FALSE;
	}
	astType = stExpressionAccess.type.get( astExp );
	return CcTypeIsModifiableObj(astType);
}
static BOOL ccExpSolveIdentifier( AST astRoot ){
	AST  astSym ;
	AST  astValue;
	AST  astType;
//	U2   usSymClass;
	U2   op;
	if( stExpressionAccess.bIllegal.get( astRoot ) ){
		return FALSE;
	}
	astSym = stExpressionAccess.result_symbol.get( astRoot );
	if( astSym != 0 ){
//		usSymClass = stSymbolInfoAccess.symClass.get( astSym );
		astType = stSymbolInfoAccess.type.get( astSym ) ;
		if( stSymbolInfoAccess.kind.get( astSym ) == SYMBOL_KIND_ENUMCONST ){
			astValue = stSymbolInfoAccess.value.get( astSym );
			astType = stValueInfoAccess.type.get( astValue ) ;
			/*debug,13/1/23,S*/
			stExpressionAccess.opKind.set( astRoot, EXPR_CONSTANT );
			stExpressionAccess.result_value.set( astRoot, astValue );
			/*debug,13/1/23,E*/
			stExpressionAccess.type.set( astRoot, astType );
			stExpressionAccess.castedType.set( astRoot, CcTypeGetNoQualType( astType ) );
			/* bModifiabe  == false */
			/* blValue = false */
			return TRUE;
		}else if( stSymbolInfoAccess.kind.get( astSym ) == SYMBOL_KIND_TYPEDEFID ){
   			CcThrowWarning( CC_EXP_OPERAND_ILLEGAL,
   					stExpressionAccess.codeScp.get( astRoot ),
   					stSymbolInfoAccess.name.get(astSym ), NULL );
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}else if( astType == 0 ){
			/* function that has not declaration  */
			AST  astfather = stExpressionAccess.parent_expression.get( astRoot );
			op = stExpressionAccess.opKind.get( astfather );
			if( op != EXPR_FUNCTIONCALL ){

       			CcThrowWarning( CC_EXP_IDENTIFIER_UNKNOWN,
       					stExpressionAccess.codeScp.get( astRoot ),
       					stSymbolInfoAccess.name.get(astSym ), NULL );
				return FALSE;
			}
			/* bModifiabe  == false */
			/* blValue = false */
			return TRUE;
		}else{
			stExpressionAccess.type.set( astRoot, astType );
			stExpressionAccess.bModifiabe.set( astRoot, ccExpGetModifiableFlg(astType) );
			astType = ccExpConvertFunc_Array(astType);
			stExpressionAccess.castedType.set( astRoot, CcTypeGetNoQualType( astType ) );
			stExpressionAccess.blValue.set( astRoot, TRUE );
			return TRUE;
		}
	}
	return FALSE;
}
static BOOL ccExpSolveArray( AST astRoot ){
	AST astLeftChild ;
	AST astRightChild;
	AST astLeftType = 0;
	AST astRightType = 0;
	AST astType = 0;
	BOOL bLeft = FALSE, bRight = FALSE;

	astLeftChild = stExpressionAccess.leftChild.get( astRoot );
	astRightChild = stExpressionAccess.rightChild.get( astRoot );
	bLeft = ccExpSolveTypes( astLeftChild );
	bRight = ccExpSolveTypes( astRightChild );
	if( bLeft  == TRUE ){
		astLeftType = stExpressionAccess.castedType.get( astLeftChild );
		if( CcTypeIsPointer( astLeftType ) ){
			astType = stTypeInfoAccess.elementType.get( astLeftType );
			stExpressionAccess.castedType.set( astRoot, astType );
			stExpressionAccess.type.set( astRoot, astType );
			stExpressionAccess.bModifiabe.set( astRoot, ccExpGetModifiableFlg(astType) );
			astType = ccExpConvertFunc_Array(astType);
			stExpressionAccess.castedType.set( astRoot, astType );
			stExpressionAccess.blValue.set( astRoot, TRUE );
		}else{
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_POINTER,
					stExpressionAccess.codeScp.get( astLeftChild ),
					NULL, NULL );
			bLeft = FALSE;
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
		}
	}else{
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
	}

	if( bRight == TRUE ){
		astRightType = stExpressionAccess.castedType.get( astRightChild );
		/*debug,13/2/7,S*/
		if(CcTypeIsBitfield(astRightType)){
			astRightType = stTypeInfoAccess.elementType.get(astRightType);
		}
		if( !CcTypeIsInteger( astRightType ) && !CcTypeIsEnum(astRightType)){
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_INTEGER,
					stExpressionAccess.codeScp.get( astRightChild ),
					NULL, NULL );
		}
		/*debug,13/2/7,E*/
	}
	return bLeft;
}
static AST  ccExprNewFakeParam( AST astArgExp){
	AST astResultChain;
	AST astSym;
	AST astArgExpType;

	stUniteChainAccess.alloc(1);
	astResultChain = stUniteChainAccess.getMax();
	astSym = CcSymNewParameter( "" );
	astArgExpType = stExpressionAccess.castedType.get( astArgExp );
	astArgExpType = CcTypeArgumentPromotion( astArgExpType );
	stSymbolInfoAccess.type.set( astSym, astArgExpType );
	stSymbolInfoAccess.codeScp.set( astSym, stExpressionAccess.codeScp.get( astArgExp ));
	stUniteChainAccess.parameter_sym.set( astResultChain , astSym );
	return astResultChain;
}
static VOID ccExpCheckArgTypes( AST astLeftChild, AST astRightChild ){
	AST astLeftType = stExpressionAccess.castedType.get( astLeftChild );
	AST astMemChain;
	AST astPreChain;
	AST astCurrChain;
	AST astMemSym=0;
	AST astMemType;
	AST astArgExpNode;
	AST astArgExp;
	AST astArgExpType;
	AST astSym;
	BOOL bNew = FALSE;

	astLeftType = stExpressionAccess.castedType.get( astLeftChild );
	if( astLeftType == 0 ){
		if( EXPR_IDENTIFIER == stExpressionAccess.opKind.get( astLeftChild )){
			astSym = stExpressionAccess.result_symbol.get( astLeftChild );
			CcThrowWarning( CC_EXP_FUNCCALL_BEFORE_DECLARE,
					stExpressionAccess.codeScp.get( astLeftChild ),
					NULL, NULL );
			CcSymSetToFunction( astSym );
			astLeftType = CcTypeAddFunction( TYPE_INT, 0 );
			stSymbolInfoAccess.type.set(astSym, astLeftType );
			stExpressionAccess.type.set( astLeftChild, astLeftType );
			stExpressionAccess.castedType.set( astLeftChild, ccExpConvertFunc_Array( astLeftType ));
			bNew = TRUE;
		}else{
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_FUNCTION,
					stExpressionAccess.codeScp.get( astLeftChild ),
					NULL, NULL );
			return ;
		}
	}else{
		astLeftType = stTypeInfoAccess.elementType.get( astLeftType );
	}
	if( bNew ){
		astArgExp = astRightChild;
		while( EXPR_ARG == stExpressionAccess.opKind.get( astArgExp )){
			astArgExp = stExpressionAccess.leftChild.get( astArgExp );
		}
		astArgExpNode = astArgExp;

		astPreChain = 0;
		astMemChain = 0;
		while( 1 ){
			astArgExpType = stExpressionAccess.castedType.get( astArgExp );
			astCurrChain = ccExprNewFakeParam( astArgExp );
			if( astPreChain != 0 ){
				stUniteChainAccess.next.set( astPreChain, astCurrChain );
				stUniteChainAccess.before.set( astCurrChain, astPreChain );
			}else{
				astMemChain = astCurrChain;
			}
			astPreChain = astCurrChain;
			if( astArgExpNode == astRightChild ){
				astArgExp = 0;
				break;
			}
			astArgExpNode = stExpressionAccess.parent_expression.get( astArgExpNode );
			astArgExp = stExpressionAccess.rightChild.get(astArgExpNode);
		}
		stTypeInfoAccess.memChain.set( astLeftType, astMemChain );
		return ;
	}
	astMemChain = stTypeInfoAccess.memChain.get( astLeftType );
	if( astMemChain == 0 && astRightChild == 0  ){
		return ;
	}
	if( astRightChild == 0 ){
		CcThrowWarning( CC_EXP_FUNCCALL_PARAM_NUM_DIFF,
				stExpressionAccess.codeScp.get( astRightChild ),
				NULL, NULL );
		return ;
	}
	if( astMemChain == 0 ){
		CcThrowWarning( CC_EXP_FUNCCALL_PARAM_NUM_DIFF,
				stExpressionAccess.codeScp.get( astRightChild ),
				NULL, NULL );
		return ;
	}
	astArgExp = astRightChild;
	while( EXPR_COMMA == stExpressionAccess.opKind.get( astArgExp )){
		stExpressionAccess.opKind.set( astArgExp, EXPR_ARG );
		astArgExp = stExpressionAccess.leftChild.get( astArgExp );
	}
	astArgExpNode = astArgExp;
	while( astMemChain ){
		astMemSym = stUniteChainAccess.parameter_sym.get( astMemChain );
		if( astMemSym == 0 ){
			break;
		}
		astMemType = stSymbolInfoAccess.type.get( astMemSym );
		astArgExpType = stExpressionAccess.castedType.get( astArgExp );
		/*debug,13/2/7,S*/
		if(CcTypeIsArray(stExpressionAccess.type.get(astArgExp))){
			astArgExpType = stExpressionAccess.type.get(astArgExp);
		}
		/*debug,13/2/7,E*/
		if( FALSE == CcTypeIsAssignable( astArgExpType, astMemType )){
			if( CcTypeIsPointer( astMemType ) && ccExprIsNullPointer( astArgExp ) ){
				;
			}else{
				U2  errorflg = CcTypeCatchAssignableFlg();
				switch( errorflg ){
				case COMP_ASSIGN_DIFFQUALIFY_POINTER:
					break;
				case COMP_ASSIGN_UNCOMPATIBLE_POINTER:
				case COMP_ASSIGN_UNCOMPATIBLE:
				default:
					CcThrowWarning( CC_EXP_ARGUMENT_NEED_ASSIGNABLE_TYPE,
							stExpressionAccess.codeScp.get( astArgExp ),
							NULL, NULL );
					break;
				}
			}
		}
		astMemChain = stUniteChainAccess.next.get( astMemChain );
		if( astArgExpNode == astRightChild ){
			astArgExp = 0;
			break;
		}
		if( astMemChain == 0 ){
			break;
		}
		astArgExpNode = stExpressionAccess.parent_expression.get( astArgExpNode );
		astArgExp = stExpressionAccess.rightChild.get(astArgExpNode);
	}
	if( astMemChain != 0 && astMemSym == 0 ){
		// variable parameters
	}else if( astMemChain != 0 && astArgExp == 0 ){
		CcThrowWarning( CC_EXP_FUNCCALL_PARAM_NUM_DIFF,
				stExpressionAccess.codeScp.get( astRightChild ),
				NULL, NULL );
	}else if( astMemChain == 0 && astArgExp != 0 ){
		CcThrowWarning( CC_EXP_FUNCCALL_PARAM_NUM_DIFF,
				stExpressionAccess.codeScp.get( astRightChild ),
				NULL, NULL );
	}
}
static BOOL  ccExpSolveFunctionCall( AST astRoot ){
	AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
	AST astRightChild = stExpressionAccess.rightChild.get( astRoot );
	AST astLeftType = 0;
	AST astType = 0;
	BOOL bLeft = FALSE, bRight = FALSE;
	/*debug,13/1/25,S*/
	while(stExpressionAccess.opKind.get(astLeftChild) == EXPR_PARENTHESE){
		astLeftChild = stExpressionAccess.leftChild.get(astLeftChild);
	}
	/*debug,13/1/25,E*/
	bLeft = ccExpSolveTypes( astLeftChild );
	if( bLeft != TRUE ){
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
	}
	if( astRightChild > 0 ){
		bRight = ccExpSolveTypes( astRightChild );
	}else{
		bRight = TRUE;
	}
	if( bLeft == TRUE && bRight == TRUE ){
		ccExpCheckArgTypes( astLeftChild, astRightChild );
		astLeftType = stExpressionAccess.castedType.get( astLeftChild );
		astLeftType = stTypeInfoAccess.elementType.get( astLeftType );
	}
	if( astLeftType >= MIN_ARRAY  ){
		astType = stTypeInfoAccess.elementType.get( astLeftType );
		stExpressionAccess.castedType.set( astRoot, astType );
		stExpressionAccess.type.set( astRoot, astType );
		/*  bModifiabe  false */
		/*  bLValue   false	 */
	}else{
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
		bLeft = FALSE;
	}
	return bLeft;
}
static BOOL  ccExpSolveMember( AST astRoot ){
	AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
	AST astRightChild = stExpressionAccess.rightChild.get( astRoot );
	AST astLeftType;
	AST astRightType=0;
	AST astSym=0;
	BOOL bModifiable;
	U2 op;
	BOOL bLeft = FALSE;

	op = stExpressionAccess.opKind.get(astRoot);
	bLeft = ccExpSolveTypes( astLeftChild );
	if( bLeft == FALSE ){
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
		return FALSE;
	}
	astLeftType = stExpressionAccess.castedType.get( astLeftChild );
	if( op == EXPR_PTRMEMBER ){
		if( !CcTypeIsPointer( astLeftType ) ){
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_POINTER,
					stExpressionAccess.codeScp.get( astLeftChild ),
					NULL, NULL );
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		astLeftType = stTypeInfoAccess.elementType.get( astLeftType );
		bModifiable = ccExpGetModifiableFlg( astLeftType );
	}else{
		bModifiable = stExpressionAccess.bModifiabe.get( astLeftChild );
	}
	if( CcTypeIsUnion ( astLeftType ) || CcTypeIsStruct( astLeftType ) ){
		astSym = ccExpGetStUnMember( astLeftType, astRightChild );
		if( astSym > 0 ){
			astRightType = stSymbolInfoAccess.type.get( astSym );
			astRightType = ccExpConvertFunc_Array( astRightType );
			stExpressionAccess.type.set( astRoot, astRightType );
			stExpressionAccess.castedType.set( astRoot,  CcTypeGetNoQualType( astRightType )  );
			if( bModifiable ){
				stExpressionAccess.bModifiabe.set( astRoot, ccExpGetModifiableFlg( astRightType ) );
			}
		}else{
			AST astToken;
			astToken = stExpressionAccess.result_temp_token.get( astRightChild );
			CcThrowWarning( CC_EXP_OPERAND_WRONGMEMBER,
					stExpressionAccess.codeScp.get( astRightChild ),
					stLexTokenAccess.name.get( astToken ), NULL );
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			bLeft = FALSE;
		}

	}else{
		CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_STRUCT_UNION,
				stExpressionAccess.codeScp.get( astLeftChild ),
				NULL, NULL );
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
		bLeft = FALSE;
	}
	stExpressionAccess.opKind.set( astRightChild, EXPR_IDENTIFIER );
	stExpressionAccess.result_symbol.set( astRightChild, astSym );
	return bLeft ;
}
static BOOL ccExpSolveCompoundLiterals( AST astRoot ){
	AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
	AST astRight;
	BOOL bLeft;
	AST astLeftType;

	bLeft = ccExpSolveTypes( astLeftChild );
	if( bLeft ){
		astLeftType = stExpressionAccess.castedType.get( astLeftChild );
		if( !CcTypeIsFunction( astLeftType ) ){
			astRight = stExpressionAccess.rightChild.get( astRoot );
			if( bLeft ){
				bLeft = ccExpCheckInitExpType( astLeftType, astRight );
			}
			stExpressionAccess.type.set(astRight, astLeftType);
			stExpressionAccess.castedType.set(astRight, astLeftType);
			stExpressionAccess.blValue.set(astRight, FALSE);
			stExpressionAccess.bModifiabe.set(astRight, FALSE);

			stExpressionAccess.type.set( astRoot, astLeftType );
			astLeftType = ccExpConvertFunc_Array( astLeftType );
			stExpressionAccess.castedType.set( astRoot, astLeftType );
			stExpressionAccess.blValue.set( astRoot, TRUE );
			stExpressionAccess.bModifiabe.set( astRoot, ccExpGetModifiableFlg( astLeftType ) );

			return bLeft;
		}
	}
	stExpressionAccess.bIllegal.set( astRoot, TRUE );
	return FALSE;
}
static BOOL ccExpSolveScalarType( AST astLeftChild ){
	AST astLeftType;
	BOOL bLeft;
	bLeft = ccExpSolveTypes( astLeftChild );
	if( bLeft == FALSE ){
		return FALSE;
	}
	astLeftType = CcTypeIntegerPromotion( stExpressionAccess.castedType.get( astLeftChild ) );
	stExpressionAccess.castedType.set( astLeftChild, astLeftType );
	if( !CcTypeIsScalar( astLeftType ) ){
		CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_SCALAR,
				stExpressionAccess.codeScp.get( astLeftChild ),
				NULL, NULL );
		return FALSE;
	}
	return TRUE;
}
static BOOL ccExpSolveBinaryInteger( AST astRoot ){
	AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
	AST astLeftType;
	AST astRightChild = stExpressionAccess.rightChild.get( astRoot );
	AST astRightType;
	BOOL bLeft = FALSE;
	BOOL bRight = FALSE;

	bLeft = ccExpSolveTypes( astLeftChild );
	bRight = ccExpSolveTypes( astRightChild );
	if( bLeft == FALSE || bRight == FALSE ){
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
		return FALSE;
	}
	astLeftType = stExpressionAccess.castedType.get( astLeftChild );
	astLeftType = CcTypeIntegerPromotion(astLeftType);

	astRightType = stExpressionAccess.castedType.get( astRightChild );
	astRightType = CcTypeIntegerPromotion(astRightType);
	if( !CcTypeIsInteger( astRightType ) || !CcTypeIsInteger( astLeftType ) ){
		if( !CcTypeIsInteger( astLeftType ) ){
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_INTEGER,
				stExpressionAccess.codeScp.get( astLeftChild ),
				NULL, NULL );
		}
		if( !CcTypeIsInteger( astRightType ) ){
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_INTEGER,
				stExpressionAccess.codeScp.get( astRightChild ),
				NULL, NULL );
		}
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
		return FALSE;
	}
	astLeftType = CcTypeGetArithConversion( astLeftType, astRightType );
	stExpressionAccess.castedType.set( astLeftChild, astLeftType );
	stExpressionAccess.castedType.set( astRightChild, astLeftType );
	stExpressionAccess.castedType.set( astRoot, astLeftType );
	stExpressionAccess.type.set( astRoot, astLeftType );
	/* blValue false */
	/* bModifiabe false */
	return TRUE;
}
static BOOL ccExpSolveShift( AST astRoot ){
	AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
	AST astLeftType;
	AST astRightChild = stExpressionAccess.rightChild.get( astRoot );
	AST astRightType;
	BOOL bLeft = FALSE;
	BOOL bRight = FALSE;

	bLeft = ccExpSolveTypes( astLeftChild );
	bRight = ccExpSolveTypes( astRightChild );
	if( bLeft == FALSE || bRight == FALSE ){
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
		return FALSE;
	}
	astLeftType = stExpressionAccess.castedType.get( astLeftChild );
	astLeftType = CcTypeIntegerPromotion(astLeftType);

	astRightType = stExpressionAccess.castedType.get( astRightChild );
	astRightType = CcTypeIntegerPromotion(astRightType);
	if( !CcTypeIsInteger( astRightType ) || !CcTypeIsInteger( astLeftType ) ){
		if( !CcTypeIsInteger( astLeftType ) ){
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_INTEGER,
				stExpressionAccess.codeScp.get( astLeftChild ),
				NULL, NULL );
		}
		if( !CcTypeIsInteger( astRightType ) ){
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_INTEGER,
				stExpressionAccess.codeScp.get( astRightChild ),
				NULL, NULL );
		}
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
		return FALSE;
	}
	stExpressionAccess.castedType.set( astLeftChild, astLeftType );
	stExpressionAccess.castedType.set( astRightChild, astRightType );
	stExpressionAccess.castedType.set( astRoot, astLeftType );
	stExpressionAccess.type.set( astRoot, astLeftType );
	/* blValue false */
	/* bModifiabe false */
	return TRUE;
}
static BOOL ccExpSolveBinaryArith( AST astRoot ){
	AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
	AST astLeftType;
	AST astRightChild = stExpressionAccess.rightChild.get( astRoot );
	AST astRightType;
	BOOL bLeft, bRight;

	bLeft = ccExpSolveTypes( astLeftChild );
	bRight = ccExpSolveTypes( astRightChild );
	if( bLeft == FALSE || bRight == FALSE ){
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
		return FALSE;
	}
	astLeftType = stExpressionAccess.castedType.get( astLeftChild );
	astRightType = stExpressionAccess.castedType.get( astRightChild );
	astLeftType = CcTypeIntegerPromotion(astLeftType);
	astRightType = CcTypeIntegerPromotion(astRightType);
	if( !CcTypeIsArith( astLeftType ) || !CcTypeIsArith( astRightType ) ){
		if( !CcTypeIsArith( astLeftType ) ){
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_ARITH,
				stExpressionAccess.codeScp.get( astLeftChild ),
				NULL, NULL );
		}
		if( !CcTypeIsArith( astRightType ) ){
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_ARITH,
				stExpressionAccess.codeScp.get( astRightChild ),
				NULL, NULL );
		}
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
		return FALSE;
	}
	astLeftType = CcTypeGetArithConversion( astLeftType, astRightType );
	stExpressionAccess.castedType.set( astLeftChild, astLeftType );
	stExpressionAccess.castedType.set( astRightChild, astLeftType );

	stExpressionAccess.castedType.set( astRoot, astLeftType );
	stExpressionAccess.type.set( astRoot, astLeftType );
	/* blValue false */
	/* bModifiabe false */
	return TRUE;
}
static BOOL ccExpSolveAdditive( AST astRoot ){
	AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
	AST astLeftType;
	AST astRightChild = stExpressionAccess.rightChild.get( astRoot );
	AST astRightType;
	BOOL bLeft, bRight;
	bLeft = ccExpSolveTypes( astLeftChild );
	bRight = ccExpSolveTypes( astRightChild );
	if( bLeft == FALSE || bRight == FALSE ){
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
		return FALSE;
	}
	astLeftType = stExpressionAccess.castedType.get( astLeftChild );
	astRightType = stExpressionAccess.castedType.get( astRightChild );

	astLeftType = CcTypeIntegerPromotion(astLeftType);
	astRightType = CcTypeIntegerPromotion(astRightType);
	if( CcTypeIsArith( astLeftType ) && CcTypeIsArith( astRightType )){
		astLeftType = CcTypeGetArithConversion( astLeftType, astRightType );
		stExpressionAccess.castedType.set( astLeftChild, astLeftType );
		stExpressionAccess.castedType.set( astRightChild, astLeftType );
	}else if(CcTypeIsPointer( astLeftType ) && CcTypeIsInteger( astRightType ) ){
		;
	}else if(CcTypeIsPointer( astRightType ) && CcTypeIsInteger( astLeftType ) ){
		astLeftType = astRightType;
	}else{
		CcThrowWarning( CC_EXP_OPERANDTYPE_ILLEGAL_ADD,
						stExpressionAccess.codeScp.get( astRoot ),
						NULL, NULL );
		bLeft = FALSE;
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
	}
	stExpressionAccess.castedType.set( astRoot, astLeftType );
	stExpressionAccess.type.set( astRoot, astLeftType );
	/* blValue false */
	/* bModifiabe false */
	return bLeft;
}
static BOOL ccExpSolveSubtraction( AST astRoot ){
	AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
	AST astLeftType;
	AST astRightChild = stExpressionAccess.rightChild.get( astRoot );
	AST astRightType;
	BOOL bLeft, bRight;
	bLeft = ccExpSolveTypes( astLeftChild );
	bRight = ccExpSolveTypes( astRightChild );
	if( bLeft == FALSE || bRight == FALSE ){
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
		return FALSE;
	}
	astLeftType = stExpressionAccess.castedType.get( astLeftChild );
	astRightType = stExpressionAccess.castedType.get( astRightChild );

	astLeftType = CcTypeIntegerPromotion(astLeftType);
	astRightType = CcTypeIntegerPromotion(astRightType);
	if( CcTypeIsArith( astLeftType ) && CcTypeIsArith( astRightType )){
		astLeftType = CcTypeGetArithConversion( astLeftType, astRightType );
		stExpressionAccess.castedType.set( astLeftChild, astLeftType );
		stExpressionAccess.castedType.set( astRightChild, astLeftType );
	}else if(CcTypeIsPointer( astLeftType ) && CcTypeIsInteger( astRightType ) ){
		;
	}else if(CcTypeIsPointer( astRightType ) && CcTypeIsInteger( astLeftType ) ){
		astLeftType = astRightType;
	}else if(CcTypeIsPointer( astRightType ) && CcTypeIsPointer( astLeftType ) ){
		astLeftType = CcTypeGetNoQualType( stTypeInfoAccess.elementType.get( astLeftType ));
		astRightType = CcTypeGetNoQualType( stTypeInfoAccess.elementType.get( astRightType ));
		if( !CcTypeIsCompatible( astRightType, astLeftType ) ){
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_SAME_POINTER,
							stExpressionAccess.codeScp.get( astRoot ),
							NULL, NULL );
		}
		astLeftType = stCoreEnvInfo.astDiffPtrType;
	}else{
		CcThrowWarning( CC_EXP_OPERANDTYPE_ILLEGAL_SUB,
						stExpressionAccess.codeScp.get( astRoot ),
						NULL, NULL );
		astLeftType = 0;
		bLeft = FALSE;
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
	}
	stExpressionAccess.castedType.set( astRoot, astLeftType );
	stExpressionAccess.type.set( astRoot, astLeftType );
	/* blValue false */
	/* bModifiabe false */
	return bLeft;
}
static BOOL ccExpSolveRelation( AST astRoot ){
	AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
	AST astLeftType;
	AST astRightChild = stExpressionAccess.rightChild.get( astRoot );
	AST astRightType;
	BOOL bLeft, bRight;

	bLeft = ccExpSolveTypes( astLeftChild );
	bRight = ccExpSolveTypes( astRightChild );
	if( bLeft == FALSE || bRight == FALSE ){
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
		return FALSE;
	}
	astLeftType = stExpressionAccess.castedType.get( astLeftChild );
	astRightType = stExpressionAccess.castedType.get( astRightChild );

	astLeftType = CcTypeIntegerPromotion(astLeftType);
	astRightType = CcTypeIntegerPromotion(astRightType);

	if( CcTypeIsArith( astLeftType ) && CcTypeIsArith( astRightType )){
		;
	}else if(CcTypeIsPointer( astRightType ) && CcTypeIsPointer( astLeftType ) ){
		;
		astLeftType = CcTypeGetNoQualType( stTypeInfoAccess.elementType.get( astLeftType ));
		astRightType = CcTypeGetNoQualType( stTypeInfoAccess.elementType.get( astRightType ));
		if( !CcTypeIsCompatible( astRightType, astLeftType ) ){
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_SAME_POINTER,
							stExpressionAccess.codeScp.get( astRoot ),
							NULL, NULL );
		}
	}else{
		CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_ARITH,
						stExpressionAccess.codeScp.get( astRoot ),
						NULL, NULL );
		bLeft = FALSE;
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
	}
	stExpressionAccess.castedType.set( astRoot, TYPE_INT );
	stExpressionAccess.type.set( astRoot, TYPE_INT );
	/* blValue false */
	/* bModifiabe false */
	return bLeft;
}
static BOOL ccExpSolveEquality( AST astRoot ){
	AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
	AST astLeftType;
	AST astRightChild = stExpressionAccess.rightChild.get( astRoot );
	AST astRightType;
	BOOL bLeft,bRight;

	bLeft = ccExpSolveTypes( astLeftChild );
	bRight = ccExpSolveTypes( astRightChild );
	if( bLeft == FALSE || bRight == FALSE  ){
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
		return FALSE;
	}
	astLeftType = stExpressionAccess.castedType.get( astLeftChild );
	astRightType = stExpressionAccess.castedType.get( astRightChild );

	astLeftType = CcTypeIntegerPromotion(astLeftType);
	astRightType = CcTypeIntegerPromotion(astRightType);
	if( CcTypeIsArith( astLeftType ) && CcTypeIsArith( astRightType )){
		;
	}else if(CcTypeIsPointer( astRightType ) && CcTypeIsPointer( astLeftType ) ){
		astLeftType = CcTypeGetNoQualType( stTypeInfoAccess.elementType.get( astLeftType ));
		astRightType = CcTypeGetNoQualType( stTypeInfoAccess.elementType.get( astRightType ));
		if( !CcTypeIsCompatible( astRightType, astLeftType ) ){
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_SAME_POINTER,
							stExpressionAccess.codeScp.get( astRoot ),
							NULL, NULL );
		}
	}else if(CcTypeIsPointer( astRightType ) && ccExprIsNullPointer( astLeftChild ) ){
		;
	}else if(ccExprIsNullPointer( astRightChild ) && CcTypeIsPointer( astLeftType ) ){
		;
	}else{
		CcThrowWarning( CC_EXP_OPERANDTYPE_ILLEGAL_SUB,
						stExpressionAccess.codeScp.get( astRoot ),
						NULL, NULL );
		bLeft = FALSE;
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
	}
	stExpressionAccess.castedType.set( astRoot, TYPE_INT );
	stExpressionAccess.type.set( astRoot, TYPE_INT );
	/* blValue false */
	/* bModifiabe false */
	return bLeft;
}
static AST ccExpSolvePostfixExp( AST astRoot ){
	U2 op;
	AST astType=0;
	AST astChild=0;
	BOOL bLeft = FALSE;
	if (stExpressionAccess.bIllegal.get(astRoot)) {
		return 0;
	}
	op = stExpressionAccess.opKind.get(astRoot);
	switch (op) {
	case EXPR_ARRAY:
		astType = ccExpSolveArray( astRoot );
		break;
	case EXPR_FUNCTIONCALL:
		astType = ccExpSolveFunctionCall( astRoot );
		break;
	case EXPR_MEMBER:
	case EXPR_PTRMEMBER:
		astType = ccExpSolveMember( astRoot );
		break;
	case EXPR_POSTINC:
	case EXPR_POSTDEC:
		astChild = stExpressionAccess.leftChild.get( astRoot );
		bLeft = ccExpSolveScalarType( astChild );
		if( bLeft == FALSE ){
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			break;
		}
		if( !stExpressionAccess.bModifiabe.get(astChild) ){
			CcThrowWarning( CC_EXP_OPERAND_NEED_MODIFIABLE,
							stExpressionAccess.codeScp.get( astChild ),
							NULL, NULL );
		}
		/* bModifiabe false */
		/* blValue false */
		astType = stExpressionAccess.castedType.get( astChild );
		stExpressionAccess.castedType.set( astRoot, astType );
		stExpressionAccess.constFlg.set( astRoot, NOT_CONSTANT );
		stExpressionAccess.type.set( astRoot, astType );
		break;
	case EXPR_COMPOUNDLITERALS:
		astType = ccExpSolveCompoundLiterals( astRoot );
		break;
	}
	return astType;
}
static BOOL ccExpSolvePrimaryExp( AST astRoot ){
	U2 op;
	BOOL bSucceed = FALSE;
	AST astType;
	AST astChild;

	if (stExpressionAccess.bIllegal.get(astRoot)) {
		return FALSE;
	}
	op = stExpressionAccess.opKind.get(astRoot);
	switch (op) {
	case EXPR_IDENTIFIER:
		bSucceed = ccExpSolveIdentifier( astRoot );
		break;
	case EXPR_CONSTANT:
		astType = stExpressionAccess.type.get( astRoot );
		stExpressionAccess.castedType.set( astRoot, CcTypeGetNoQualType( astType ) );
		stExpressionAccess.constValue.set( astRoot, stExpressionAccess.result_value.get( astRoot ));
		bSucceed = TRUE;
		break;
	case EXPR_STRING:
		astType = stExpressionAccess.type.get( astRoot );
		astType = ccExpConvertFunc_Array( astType );
		stExpressionAccess.castedType.set( astRoot, CcTypeGetNoQualType( astType ) );
		bSucceed = TRUE;
		break;
	case EXPR_DECLARATION:
		astChild = stExpressionAccess.result_declaration.get( astRoot );
		astType = CcDeclGetTypeInfo( astChild );
		if (astType > 0 ){
			stExpressionAccess.type.set( astRoot, astType );
			stExpressionAccess.castedType.set( astRoot, astType );
			bSucceed = TRUE;
		}
		break;
	case EXPR_STATEMENT:
		astChild = stExpressionAccess.result_statement.get( astRoot );
		astType = CcStmtGetLastType( astChild );
		if (astType > 0 ){
			stExpressionAccess.castedType.set( astRoot, CcTypeGetNoQualType( astType ) );
			stExpressionAccess.type.set( astRoot, CcTypeGetNoQualType( astType ) );
			bSucceed = TRUE;
		}
		break;
	case EXPR_PARENTHESE:
		astChild = stExpressionAccess.leftChild.get( astRoot );
		bSucceed = ccExpSolveTypes( astChild );
		if( bSucceed ){
			astType = stExpressionAccess.type.get( astChild );
			stExpressionAccess.castedType.set( astRoot, CcTypeGetNoQualType( astType ) );
			stExpressionAccess.type.set( astRoot, astType );
			stExpressionAccess.constValue.set( astRoot, stExpressionAccess.constValue.get( astChild ));
			/*debug,13/1/31,S*/
			stExpressionAccess.bModifiabe.set( astRoot, stExpressionAccess.bModifiabe.get(astChild) );
			/*debug,13/1/31,E*/
		}
		break;
	case EXPR_INITEXPRLIST:
		break;
	}
	if( !bSucceed ){
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
	}
	return bSucceed;
}
static BOOL ccExpSolveTypes( AST astRoot ){
	U2 op;

	if (astRoot == 0 || stExpressionAccess.bIllegal.get(astRoot)) {
		return FALSE;
	}
	op = stExpressionAccess.opKind.get(astRoot);
	switch (op) {
	case EXPR_IDENTIFIER:
	case EXPR_CONSTANT:
	case EXPR_STRING:
	case EXPR_DECLARATION:
	case EXPR_STATEMENT:
	case EXPR_INITEXPRLIST:
	case EXPR_PARENTHESE:
		return ccExpSolvePrimaryExp( astRoot );
	case EXPR_ARRAY:
	case EXPR_FUNCTIONCALL:
	case EXPR_MEMBER:
	case EXPR_PTRMEMBER:
	case EXPR_POSTINC:
	case EXPR_POSTDEC:
	case EXPR_COMPOUNDLITERALS:
		return ccExpSolvePostfixExp( astRoot );
	case EXPR_PREINC:
	case EXPR_PREDEC:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		BOOL bLeft;
		AST astLeftType;

		bLeft = ccExpSolveScalarType( astLeftChild );
		if( bLeft == FALSE ){
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		if( !stExpressionAccess.bModifiabe.get( astLeftChild ) ){
			CcThrowWarning( CC_EXP_OPERAND_NEED_MODIFIABLE,
							stExpressionAccess.codeScp.get( astLeftChild ),
							NULL, NULL );
		}
		/* bModifiabe false */
		/* blValue false */
		astLeftType = stExpressionAccess.castedType.get( astLeftChild );
		stExpressionAccess.castedType.set( astRoot, astLeftType );
		stExpressionAccess.type.set( astRoot, astLeftType );
		return TRUE;
	}
	case EXPR_ADDRESS:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		AST astLeftType;
		BOOL bLeft;

		bLeft = ccExpSolveTypes( astLeftChild );
		if( bLeft == FALSE ){
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		astLeftType = stExpressionAccess.type.get( astLeftChild );
		if( CcTypeIsBitfield(astLeftType) ){
			CcThrowWarning( CC_EXP_OP_ADDRESS_OF_BIT,
							stExpressionAccess.codeScp.get( astLeftChild ),
							NULL, NULL );
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		if( EXPR_IDENTIFIER == stExpressionAccess.opKind.get( astLeftChild ) ){
			AST astSym = stExpressionAccess.result_symbol.get( astLeftChild );
			if( CLASS_REGISTER == stSymbolInfoAccess.symClass.get( astSym ) ){
				CcThrowWarning( CC_EXP_OP_ADDRESS_OF_REGISTER,
								stExpressionAccess.codeScp.get( astLeftChild ),
								NULL, NULL );
			}
		}
		astLeftType = CcTypeAddPointer( astLeftType, 0, TYPEQUAL_CONST );
		stExpressionAccess.castedType.set( astRoot, astLeftType );
		stExpressionAccess.type.set( astRoot, astLeftType );
		/* bModifiabe false */
		/* blValue false */
		return TRUE;
	}
	case EXPR_ASTERISK:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		AST astLeftType;
		BOOL bLeft;

		bLeft = ccExpSolveTypes( astLeftChild );
		if( bLeft == FALSE ){
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		astLeftType = stExpressionAccess.castedType.get( astLeftChild );
		if( !CcTypeIsPointer(astLeftType) ){
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_POINTER,
							stExpressionAccess.codeScp.get( astLeftChild ),
							NULL, NULL );
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		astLeftType = stTypeInfoAccess.elementType.get( astLeftType );
		stExpressionAccess.type.set( astRoot, astLeftType );
		if( !CcTypeIsFunction( astLeftType )){
			stExpressionAccess.blValue.set( astRoot, TRUE );
			stExpressionAccess.bModifiabe.set( astRoot, ccExpGetModifiableFlg( astLeftType ) );
		}else{
			/* blValue false */
			/* bModifiabe false */
		}
		astLeftType = ccExpConvertFunc_Array( astLeftType );
		stExpressionAccess.castedType.set( astRoot, CcTypeGetNoQualType( astLeftType ) );
		return TRUE;
	}
	case EXPR_PLUS:
	case EXPR_MINUS:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		AST astLeftType;
		BOOL bLeft;
		bLeft = ccExpSolveTypes( astLeftChild );
		if( bLeft == FALSE ){
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		astLeftType = stExpressionAccess.castedType.get( astLeftChild );
		astLeftType = CcTypeIntegerPromotion( astLeftType );
		stExpressionAccess.castedType.set( astLeftChild, astLeftType );
		if( !CcTypeIsArith( astLeftType ) ){
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_ARITH,
							stExpressionAccess.codeScp.get( astLeftChild ),
							NULL, NULL );
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		stExpressionAccess.castedType.set( astRoot, astLeftType );
		stExpressionAccess.type.set( astRoot, astLeftType );
		/* blValue false */
		/* bModifiabe false */
		return TRUE;
	}
	case EXPR_NEGATION:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		BOOL bLeft;
		bLeft = ccExpSolveScalarType(astLeftChild);
		if( bLeft == FALSE ){
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		stExpressionAccess.castedType.set( astRoot, TYPE_INT );
		stExpressionAccess.type.set( astRoot, TYPE_INT );
		/* blValue false */
		/* bModifiabe false */
		return TRUE;
	}
	case EXPR_BIT_NEGATION:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		AST astLeftType;
		BOOL bLeft;
		bLeft = ccExpSolveTypes( astLeftChild );
		if( bLeft == FALSE ){
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		astLeftType = stExpressionAccess.castedType.get( astLeftChild );
		astLeftType = CcTypeIntegerPromotion( astLeftType );
		stExpressionAccess.castedType.set( astLeftChild, astLeftType );
		if( !CcTypeIsInteger( astLeftType ) ){
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_INTEGER,
							stExpressionAccess.codeScp.get( astLeftChild ),
							NULL, NULL );
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
		}
		stExpressionAccess.castedType.set( astRoot, astLeftType );
		stExpressionAccess.type.set( astRoot, astLeftType );
		/* blValue false */
		/* bModifiabe false */
		return TRUE;
	}
	case EXPR_SIZEOF:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		AST astLeftType;
		BOOL bLeft;

		bLeft = ccExpSolveTypes( astLeftChild );
		if( bLeft == FALSE ){
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		astLeftType = stExpressionAccess.type.get( astLeftChild );
		if( CcTypeIsFunction( astLeftType ) ){
			CcThrowWarning( CC_EXP_OPERANDTYPE_CANNOT_BE_FUNC,
							stExpressionAccess.codeScp.get( astLeftChild ),
							"sizeof", NULL );
		}else if (CcTypeIsBitfield(astLeftType )){
			CcThrowWarning( CC_EXP_OPERANDTYPE_CANNOT_BE_BIT,
							stExpressionAccess.codeScp.get( astLeftChild ),
							"sizeof", NULL );
		}
		stExpressionAccess.castedType.set( astRoot, stCoreEnvInfo.astSizeofType );
		stExpressionAccess.type.set( astRoot, stCoreEnvInfo.astSizeofType );
		/* blValue false */
		/* bModifiabe false */
		return TRUE;
	}
	case EXPR_CAST:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		AST astLeftType;
		AST astRightChild = stExpressionAccess.rightChild.get( astRoot );
		AST astRightType;
		BOOL bLeft, bRight;

		bLeft = ccExpSolveTypes( astLeftChild );
		bRight = ccExpSolveTypes( astRightChild );
		if( bLeft == FALSE || bRight == FALSE ){
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		astLeftType = stExpressionAccess.type.get( astLeftChild );
		/*debug,13/1/31,S*/
		if( !CcCastTypeIsScalar( astLeftType )){
		/*debug,13/1/31,E*/
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_SCALAR,
				stExpressionAccess.codeScp.get( astLeftChild ),
				"cast", NULL );
		}
		astRightType = stExpressionAccess.castedType.get( astRightChild );
		/*debug,12/10/04,S*/
		if( stTypeInfoAccess.typeKind.get(astRightType) == TYPEKIND_BITFIELD ){
			astRightType = stTypeInfoAccess.elementType.get(astRightType);
		}
		/*debug,12/10/04,E*/
		/*debug,13/1/31,S*/
		if( !CcCastTypeIsScalar( astRightType ) ){
		/*debug,13/1/31,S*/
			CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_SCALAR,
				stExpressionAccess.codeScp.get( astLeftChild ),
				"cast", NULL );
		}
		stExpressionAccess.castedType.set( astRoot, astLeftType );
		stExpressionAccess.type.set( astRoot, astLeftType );
		/* blValue false */
		/* bModifiabe false */
		return TRUE;
	}
	case EXPR_MUL:
	case EXPR_DIV:
		return ccExpSolveBinaryArith( astRoot );
	case EXPR_MOD:
		return ccExpSolveBinaryInteger( astRoot );
	case EXPR_LEFTSHIFT:
	case EXPR_RIGHTSHIFT:
		return ccExpSolveShift( astRoot );
	case EXPR_BIT_AND:
	case EXPR_BIT_EXOR:
	case EXPR_BIT_INOR:
		return ccExpSolveBinaryInteger( astRoot );
	case EXPR_ADD:
		return ccExpSolveAdditive( astRoot );
	case EXPR_SUB:
		return ccExpSolveSubtraction( astRoot );
	case EXPR_GREATER:
	case EXPR_GREATEREQU:
	case EXPR_LESS:
	case EXPR_LESSEQU:
		return ccExpSolveRelation( astRoot );
	case EXPR_EQUAL:
	case EXPR_UNEQUAL:
		return ccExpSolveEquality( astRoot );
	case EXPR_LOGIC_AND:
	case EXPR_LOGIC_OR:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		AST astRightChild = stExpressionAccess.rightChild.get( astRoot );
		BOOL bLeft, bRight;
		bLeft = ccExpSolveScalarType( astLeftChild );
		bRight = ccExpSolveScalarType( astRightChild );
		if( bLeft == FALSE || bRight == FALSE ){
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		stExpressionAccess.castedType.set( astRoot, TYPE_INT );
		stExpressionAccess.type.set( astRoot, TYPE_INT );
		/* blValue false */
		/* bModifiabe false */
		return TRUE;
	}
	case EXPR_CONDITION:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		AST astRightChild = stExpressionAccess.rightChild.get( astRoot );
		AST astRightType;
		BOOL bLeft, bRight;
		bLeft = ccExpSolveScalarType( astLeftChild );
		bRight = ccExpSolveTypes( astRightChild );
		if( bLeft == FALSE || bRight == FALSE ){
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		astRightType = stExpressionAccess.castedType.get( astRightChild );
		stExpressionAccess.type.set( astRoot, astRightType );
		stExpressionAccess.castedType.set( astRoot, astRightType );
		/* blValue false */
		/* bModifiabe false */
		return TRUE;
	}
	case EXPR_COLON:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		AST astLeftType;
		AST astRightChild = stExpressionAccess.rightChild.get( astRoot );
		AST astRightType;
		BOOL bLeft,bRight;
		bLeft = ccExpSolveTypes( astLeftChild );
		bRight = ccExpSolveTypes( astRightChild );
		if( bLeft == FALSE || bRight == FALSE  ){
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		astLeftType = stExpressionAccess.castedType.get( astLeftChild );
		astRightType = stExpressionAccess.castedType.get( astRightChild );
		astLeftType = CcTypeIntegerPromotion( astLeftType );
		astRightType = CcTypeIntegerPromotion( astRightType );

		if( CcTypeIsCompatible( astLeftType, astRightType ) ){
			astLeftType = CcTypeGetCompositeType( astLeftType, astRightType );
			/*debug,12/10/04,S*/
			stExpressionAccess.castedType.set( astRoot, astLeftType );
			/*debug,12/10/04,E*/
			return TRUE;
			/* blValue false */
			/* bModifiabe false */
		}
		CcThrowWarning( CC_EXP_OPERANDTYPE_NEED_SAME_TYPE,
			stExpressionAccess.codeScp.get( astLeftChild ),
			 ":", NULL );
		stExpressionAccess.bIllegal.set( astRoot, TRUE );
		return FALSE;
	}
	case EXPR_ASSIGN:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		AST astLeftType;
		AST astRightChild = stExpressionAccess.rightChild.get( astRoot );
		AST astRightType;
		BOOL bLeft, bRight;

		/*debug,12/10/04,S*/
		while( stExpressionAccess.opKind.get(astLeftChild) == EXPR_PARENTHESE ){
			astLeftChild = stExpressionAccess.leftChild.get( astLeftChild );
		}
		/*debug,12/10/04,E*/

		bLeft = ccExpSolveTypes( astLeftChild );
		bRight = ccExpSolveTypes( astRightChild );

		if( bLeft == FALSE || bRight == FALSE ){
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		astLeftType = stExpressionAccess.castedType.get( astLeftChild );
		astRightType = stExpressionAccess.castedType.get( astRightChild );
		if( !CcTypeIsAssignable( astRightType, astLeftType ) ){
			if( CcTypeIsPointer( astLeftType ) && ccExprIsNullPointer( astRightChild ) ){
				;
			}else{
				U2  errorflg = CcTypeCatchAssignableFlg();
				if( errorflg == COMP_ASSIGN_UNCOMPATIBLE_POINTER ){
					CcThrowWarning( CC_EXP_ASSIGNMENT_DIFFPTR,
						stExpressionAccess.codeScp.get( astLeftChild ),
						"=", NULL );
					stExpressionAccess.bIllegal.set( astRoot, TRUE );
					return FALSE;
				}else if( errorflg == COMP_ASSIGN_DIFFQUALIFY_POINTER ){
					CcThrowWarning( CC_EXP_ASSIGNMENT_PTR_DIFFQUAL,
						stExpressionAccess.codeScp.get( astLeftChild ),
						 "=", NULL );
					stExpressionAccess.bIllegal.set( astRoot, TRUE );
					return FALSE;
				}else{
					CcThrowWarning( CC_EXP_ASSIGNMENT_DIFFTYPE,
						stExpressionAccess.codeScp.get( astLeftChild ),
						"=", NULL );
					stExpressionAccess.bIllegal.set( astRoot, TRUE );
					return FALSE;
				}
			}
		}
		if( !ccExpIsModifiable( astLeftChild ) ){
			CcThrowWarning( CC_EXP_OPERAND_NEED_MODIFIABLE,
				stExpressionAccess.codeScp.get( astLeftChild ),
				"=", NULL );
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
		}
		astLeftType = stExpressionAccess.type.get( astLeftChild );
		stExpressionAccess.type.set( astRoot, astLeftType );
		stExpressionAccess.castedType.set(  astRoot, astLeftType  );
		/* blValue false */
		/* bModifiabe false */
		return TRUE;
	}
	case EXPR_MUL_ASSIGN:
	case EXPR_DIV_ASSIGN:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		AST astLeftType;
		BOOL bRes = ccExpSolveBinaryArith( astRoot );
		if( !bRes ){
			return bRes;
		}
		astLeftType = stExpressionAccess.type.get( astLeftChild );
		stExpressionAccess.type.set( astRoot, astLeftType );
		stExpressionAccess.castedType.set(  astRoot, astLeftType  );
		/* blValue false */
		/* bModifiabe false */
		return TRUE;
	}
	case EXPR_MOD_ASSIGN:
	case EXPR_BITAND_ASSIGN:
	case EXPR_BITEXOR_ASSIGN:
	case EXPR_BITINOR_ASSIGN:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		AST astLeftType;
		BOOL bRes = ccExpSolveBinaryInteger( astRoot );
		if( !bRes ){
			return bRes;
		}
		astLeftType = stExpressionAccess.type.get( astLeftChild );
		stExpressionAccess.type.set( astRoot, astLeftType );
		stExpressionAccess.castedType.set(  astRoot, astLeftType  );
		/* blValue false */
		/* bModifiabe false */
		return TRUE;
	}
	case EXPR_LSHT_ASSIGN:
	case EXPR_RSHT_ASSIGN:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		BOOL bRes = ccExpSolveShift( astRoot );
		AST  astLeftType;

		if( !bRes ){
			return bRes;
		}

		astLeftType = stExpressionAccess.type.get( astLeftChild );
		stExpressionAccess.type.set( astRoot, astLeftType );
		stExpressionAccess.castedType.set(  astRoot, astLeftType  );
		/* blValue false */
		/* bModifiabe false */
		return TRUE;
	}
	case EXPR_ADD_ASSIGN:
	case EXPR_SUB_ASSIGN:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		AST astLeftType;
		BOOL bFlag =  ccExpSolveAdditive( astRoot );
		AST astRightChild;
		AST astRightType;

		if ( bFlag == FALSE ){
			return FALSE;
		}
		astRightChild = stExpressionAccess.rightChild.get( astRoot );
		astRightType = stExpressionAccess.castedType.get( astRightChild );
		if( CcTypeIsPointer( astRightType )){
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		astLeftType = stExpressionAccess.type.get( astLeftChild );
		stExpressionAccess.type.set( astRoot, astLeftType );
		stExpressionAccess.castedType.set(  astRoot, astLeftType  );
		/* blValue false */
		/* bModifiabe false */
		return TRUE;
	}
	case EXPR_COMMA:{
		AST astChild = stExpressionAccess.leftChild.get( astRoot );
		AST astRightType;
		BOOL bRight;
		ccExpSolveTypes( astChild );
		astChild = stExpressionAccess.rightChild.get( astRoot );
		bRight = ccExpSolveTypes( astChild );
		if( !bRight ){
			stExpressionAccess.bIllegal.set( astRoot, TRUE );
			return FALSE;
		}
		astRightType = stExpressionAccess.castedType.get( astChild );
		stExpressionAccess.castedType.set( astRoot, astRightType );
		stExpressionAccess.type.set( astRoot, astRightType );
		/* blValue false */
		/* bModifiabe false */
		return TRUE;
	}
	case EXPR_ARG:{
		AST astChild = stExpressionAccess.leftChild.get( astRoot );
		ccExpSolveTypes( astChild );
		astChild = stExpressionAccess.rightChild.get( astRoot );
		ccExpSolveTypes( astChild );
		/* blValue false */
		/* bModifiabe false */
		return TRUE;
	}
	}
	return FALSE;

}
static S2 ccExpGetStarConstFlg( AST astType, S2 constFlg ){
	if( constFlg < VARIABLE ){
		constFlg++;
		if( CcTypeIsFunction( astType ) || CcTypeIsArray( astType ) ){
			if( constFlg == VARIABLE ){
				constFlg--;
			}
		}
	}
	return constFlg;
}
static S2 ccExpGetAddrConstFlg( S2 constFlg ){
//	if( constFlg < GBL_VARIABLE ){
//		constFlg++;
//		if( CcTypeIsFunction( astType ) || CcTypeIsArray( astType ) ){
//			if( constFlg == GBL_VARIABLE ){
//				constFlg--;
//			}
//		}
//	}
	if( constFlg <= VARIABLE ){
		constFlg--;
	}
	return constFlg;
}
static BOOL ccExpIsAddrConstFlg( S2 constFlg ){
	return constFlg < VARIABLE;
}
static BOOL ccExpIsFixedFlg( S2 constFlg ){
	return constFlg >= 0;
}
static S2 ccExpSetPostfixExp( AST astRoot ){
	U2 op;
	S2 constFlg = NOT_CONSTANT;
	S2 constFlgLeft = NOT_CONSTANT, constFlgRight = NOT_CONSTANT;
	AST astType=0;
	AST astLeftChild=0;
	AST astRightChild=0;

	if (stExpressionAccess.bIllegal.get(astRoot)) {
		return constFlg;
	}
	op = stExpressionAccess.opKind.get(astRoot);
	switch (op) {
	case EXPR_ARRAY:
		astRightChild = stExpressionAccess.rightChild.get( astRoot );
		constFlgRight = ccExpSetFlag( astRightChild );

		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		constFlgLeft = ccExpSetFlag( astLeftChild );
		if( constFlgRight != CONSTANT_VALUE ){
			constFlg = NOT_CONSTANT;
			break;
		}
		/*debug,13/2/1,S*/
		astType = stExpressionAccess.type.get(astLeftChild);
		if(CcTypeIsConst(astType)){
			constFlg = INIT_CONSTANT;
			break;
		}
		/*debug,13/2/1,E*/
		if( ccExpIsFixedFlg( constFlgLeft ) ){
			constFlg = constFlgLeft;
		}else if( ccExpIsAddrConstFlg( constFlgLeft ) ){
			astType = stExpressionAccess.type.get( astRoot );
			constFlg = ccExpGetStarConstFlg( astType, constFlgLeft);
		}else{
			constFlg = NOT_CONSTANT;
		}
		break;
	case EXPR_FUNCTIONCALL:
		astRightChild = stExpressionAccess.rightChild.get( astRoot );
		constFlgRight = ccExpSetFlag( astRightChild );
		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		constFlgLeft = ccExpSetFlag( astLeftChild );
		constFlg = NOT_CONSTANT;
		break;
	case EXPR_MEMBER:
		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		constFlg = ccExpSetFlag( astLeftChild );
		break;
	case EXPR_PTRMEMBER:
		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		constFlgLeft = ccExpSetFlag( astLeftChild );
		if( ccExpIsFixedFlg( constFlgLeft ) ){
			constFlg = constFlgLeft;
		}else if( ccExpIsAddrConstFlg( constFlgLeft ) ){
			astType = stExpressionAccess.type.get( astRoot );
			constFlg = ccExpGetStarConstFlg( astType, constFlgLeft);
		}else{
			constFlg = NOT_CONSTANT;
		}
		break;
	case EXPR_POSTINC:
	case EXPR_POSTDEC:
		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		constFlgLeft = ccExpSetFlag( astLeftChild );
		constFlg = NOT_CONSTANT;
		break;
	case EXPR_COMPOUNDLITERALS:
		astRightChild = stExpressionAccess.rightChild.get( astRoot );
		constFlg = ccExpSetFlag( astRightChild );
		break;
	}
	stExpressionAccess.constFlg.set( astRoot, constFlg );
	return constFlg;
}
static S2 ccExpSetPrimaryExp( AST astRoot ){
	U2 op;
	S2 constflg=NOT_CONSTANT;
	AST astType;
	AST astChild;

	if (stExpressionAccess.bIllegal.get(astRoot)) {
		return constflg;
	}
	op = stExpressionAccess.opKind.get(astRoot);
	switch (op) {
	case EXPR_IDENTIFIER:
		astType = stExpressionAccess.type.get( astRoot );
		if( CcTypeIsFunction( astType )){
			constflg = INIT_CONSTANT;
		}else if( CcTypeIsArray( astType ) ){
			constflg = ccExpGetAddrConstFlg( VARIABLE ) ;
		}else{
			constflg = VARIABLE ;
		}
		break;
	case EXPR_CONSTANT:
		constflg = CONSTANT_VALUE ; ;
		break;
	case EXPR_STRING:
		constflg = ccExpGetAddrConstFlg( VARIABLE ) ;
		break;
	case EXPR_DECLARATION:
	case EXPR_STATEMENT:
		break;
	case EXPR_PARENTHESE:
		astChild = stExpressionAccess.leftChild.get( astRoot );
		constflg = ccExpSetFlag( astChild );
		break;
	case EXPR_INITEXPRLIST:
		astChild = stExpressionAccess.result_exprlist.get( astRoot );
		constflg = stExpressionListAccess.constFlg.get( astChild );
		break;
	}
	stExpressionAccess.constFlg.set( astRoot, constflg );
	if( constflg == CONSTANT_VALUE ){
		ccExpCalcute( astRoot );
	}
	return constflg;
}
static S2 ccExpSetFlag( AST astRoot ){
	U2 op;
	S2 constflg = NOT_CONSTANT;
	AST astLeftChild;
	if (astRoot == 0 || stExpressionAccess.bIllegal.get(astRoot)) {
		return NOT_CONSTANT;
	}
	op = stExpressionAccess.opKind.get(astRoot);
	switch (op) {
	case EXPR_IDENTIFIER:
	case EXPR_CONSTANT:
	case EXPR_STRING:
	case EXPR_DECLARATION:
	case EXPR_STATEMENT:
	case EXPR_INITEXPRLIST:
	case EXPR_PARENTHESE:
		return ccExpSetPrimaryExp( astRoot );
	case EXPR_ARRAY:
	case EXPR_FUNCTIONCALL:
	case EXPR_MEMBER:
	case EXPR_PTRMEMBER:
	case EXPR_POSTINC:
	case EXPR_POSTDEC:
	case EXPR_COMPOUNDLITERALS:
		return ccExpSetPostfixExp( astRoot );
	case EXPR_PREINC:
	case EXPR_PREDEC:
	{
		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		ccExpSetFlag( astLeftChild );
		constflg = NOT_CONSTANT;
		break;
	}
	case EXPR_ADDRESS:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		S2  constFlgLeft;

		constFlgLeft = ccExpSetFlag( astLeftChild );
		if( ccExpIsAddrConstFlg( constFlgLeft ) ){
			constflg = ccExpGetAddrConstFlg(constFlgLeft);
		}else if( constFlgLeft == VARIABLE ) {
			constflg = ccExpGetAddrConstFlg(VARIABLE);
		}else{
			constflg = constFlgLeft;
		}
		break;
	}
	case EXPR_ASTERISK:
	{
		AST astLeftChild ;
		AST astType;
		S2  constFlgLeft;

		astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		constFlgLeft = ccExpSetFlag( astLeftChild );
		if( ccExpIsFixedFlg( constFlgLeft ) ){
			constflg = constFlgLeft;
		}else if( ccExpIsAddrConstFlg( constFlgLeft ) ){
			astType = stExpressionAccess.type.get( astRoot );
			constflg = ccExpGetStarConstFlg(astType, constFlgLeft);
		}else{
			constflg = NOT_CONSTANT;
		}
		break;
	}
	case EXPR_PLUS:
	case EXPR_MINUS:
	case EXPR_NEGATION:
	case EXPR_BIT_NEGATION:
	{
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		constflg = ccExpSetFlag( astLeftChild );
		break;
	}
	case EXPR_SIZEOF:
	{
		VARVALUE value;
		AST astLeftChild = stExpressionAccess.leftChild.get( astRoot );
		AST astValue;

		value.sign = 1;
		value.u8Remainder = CcTypeGetTypeSize( stExpressionAccess.type.get( astLeftChild ));
		astValue = CcValueAddVarValue( stExpressionAccess.type.get( astRoot ), value  );
		stExpressionAccess.constValue.set( astRoot, astValue );
		constflg = CONSTANT_VALUE;
		break;
	}
	case EXPR_CAST:
	{
		constflg = ccExpSetFlag( stExpressionAccess.rightChild.get( astRoot ) );
		break;
	}
	case EXPR_MUL:
	case EXPR_DIV:
	case EXPR_MOD:
	case EXPR_LEFTSHIFT:
	case EXPR_RIGHTSHIFT:
	case EXPR_BIT_AND:
	case EXPR_BIT_EXOR:
	case EXPR_BIT_INOR:
	case EXPR_ADD:
	case EXPR_SUB:
	case EXPR_GREATER:
	case EXPR_GREATEREQU:
	case EXPR_LESS:
	case EXPR_LESSEQU:
	case EXPR_EQUAL:
	case EXPR_UNEQUAL:
	case EXPR_LOGIC_AND:
	case EXPR_LOGIC_OR:
	case EXPR_CONDITION:
	case EXPR_COLON:
	{
		S2  constFlgLeft, constFlgRight;

		constFlgLeft = ccExpSetFlag( stExpressionAccess.leftChild.get( astRoot ) );
		constFlgRight = ccExpSetFlag(stExpressionAccess.rightChild.get( astRoot ) );
		if( constFlgLeft == NOT_CONSTANT || constFlgRight == NOT_CONSTANT ){
			constflg = NOT_CONSTANT;
		}else if( ccExpIsFixedFlg( constFlgLeft ) && ccExpIsFixedFlg ( constFlgRight ) ){
			if( constFlgLeft == CONSTANT_VALUE && constFlgRight == CONSTANT_VALUE ){
				constflg = CONSTANT_VALUE;
			}else{
				constflg = INIT_CONSTANT;
			}
		}else if( !ccExpIsFixedFlg( constFlgLeft ) ){
			constflg = constFlgLeft;
		}else{
			constflg = constFlgRight;
		}
		break;
	}
	case EXPR_ASSIGN:
	case EXPR_MUL_ASSIGN:
	case EXPR_DIV_ASSIGN:
	case EXPR_MOD_ASSIGN:
	case EXPR_BITAND_ASSIGN:
	case EXPR_BITEXOR_ASSIGN:
	case EXPR_BITINOR_ASSIGN:
	case EXPR_LSHT_ASSIGN:
	case EXPR_RSHT_ASSIGN:
	case EXPR_ADD_ASSIGN:
	case EXPR_SUB_ASSIGN:
	case EXPR_COMMA:
	case EXPR_ARG:
		ccExpSetFlag(stExpressionAccess.leftChild.get( astRoot ) );
		ccExpSetFlag(stExpressionAccess.rightChild.get( astRoot ) );
		constflg = NOT_CONSTANT;
		break;
	}
	stExpressionAccess.constFlg.set( astRoot, constflg );
	if( constflg == CONSTANT_VALUE ){
		ccExpCalcute( astRoot );
	}
	return constflg;
}
static AST ccExpCalcute( AST astRoot ){
	U2 op;
	AST astValue=0;
	AST astLChild=0, astRChild=0;
	AST astLValue=0, astRValue=0;
	AST astType;

	if (astRoot == 0 || stExpressionAccess.bIllegal.get(astRoot)) {
		return 0;
	}
	op = stExpressionAccess.opKind.get(astRoot);
	switch (op) {
	case EXPR_CONSTANT:
		astValue = stExpressionAccess.result_value.get( astRoot );
		break;
	case EXPR_IDENTIFIER:
	case EXPR_STRING:
	case EXPR_DECLARATION:
	case EXPR_STATEMENT:
	case EXPR_INITEXPRLIST:
		break;
	case EXPR_PARENTHESE:
		astLChild = stExpressionAccess.leftChild.get( astRoot );
		astValue = ccExpCalcute( astLChild );
		break;
	case EXPR_ARRAY:
	case EXPR_FUNCTIONCALL:
	case EXPR_MEMBER:
	case EXPR_PTRMEMBER:
	case EXPR_POSTINC:
	case EXPR_POSTDEC:
	case EXPR_COMPOUNDLITERALS:
	case EXPR_PREINC:
	case EXPR_PREDEC:
	case EXPR_ADDRESS:
	case EXPR_ASTERISK:
		break;
	case EXPR_PLUS:
		astLChild = stExpressionAccess.leftChild.get( astRoot );
		astValue = ccExpCalcute( astLChild );
		break;
	case EXPR_MINUS:
		astLChild = stExpressionAccess.leftChild.get( astRoot );
		astValue = ccExpCalcute( astLChild );
		if(astValue){
			astValue = CcCalMinus( astValue );
		}
		break;
	case EXPR_NEGATION:
		astLChild = stExpressionAccess.leftChild.get( astRoot );
		astValue = ccExpCalcute( astLChild );
		if(astValue){
			astValue = CcCalNegation( astValue );
		}
		break;
	case EXPR_BIT_NEGATION:
		astLChild = stExpressionAccess.leftChild.get( astRoot );
		astValue = ccExpCalcute( astLChild );
		if(astValue){
			astValue = CcCalBitNegation( astValue );
		}
		break;
	case EXPR_SIZEOF:
	{
		VARVALUE size;
		astLChild = stExpressionAccess.leftChild.get( astRoot );
		astType = stExpressionAccess.type.get( astLChild );
		size.sign = 1;
		size.u8Remainder = 1;
		while( CcTypeIsArray( astType )){
			size.u8Remainder *= stTypeInfoAccess.size.get( astType );
			astType = stTypeInfoAccess.elementType.get( astType );
		}
		size.u8Remainder *= stTypeInfoAccess.size.get( astType );
		astType = stExpressionAccess.type.get( astRoot );
		astValue = CcValueAddVarValue(astType, size );
		break;
	}
	case EXPR_CAST:
		astType = stExpressionAccess.type.get( astRoot );
		/*debug,12/11/08,S*/
		astRChild = stExpressionAccess.rightChild.get(astRoot);
		astValue = ccExpCalcute( astRChild );
		/*debug,12/11/08,S*/
		if(astValue){
			astValue = CcCalCastTo( astValue, astType );
		}
		break;
	case EXPR_MUL:
	case EXPR_DIV:
	case EXPR_MOD:
	case EXPR_LEFTSHIFT:
	case EXPR_RIGHTSHIFT:
	case EXPR_BIT_AND:
	case EXPR_BIT_EXOR:
	case EXPR_BIT_INOR:
	case EXPR_ADD:
	case EXPR_SUB:
	case EXPR_GREATER:
	case EXPR_GREATEREQU:
	case EXPR_LESS:
	case EXPR_LESSEQU:
	case EXPR_EQUAL:
	case EXPR_UNEQUAL:
	case EXPR_LOGIC_AND:
	case EXPR_LOGIC_OR:
	case EXPR_CONDITION:
	case EXPR_COLON:
		astLChild = stExpressionAccess.leftChild.get( astRoot );
		astRChild = stExpressionAccess.rightChild.get( astRoot );
		astType = stExpressionAccess.type.get( astRoot );
		astLValue = ccExpCalcute( astLChild );
		astRValue = ccExpCalcute( astRChild );
		break;
	case EXPR_ASSIGN:
	case EXPR_MUL_ASSIGN:
	case EXPR_DIV_ASSIGN:
	case EXPR_MOD_ASSIGN:
	case EXPR_BITAND_ASSIGN:
	case EXPR_BITEXOR_ASSIGN:
	case EXPR_BITINOR_ASSIGN:
	case EXPR_LSHT_ASSIGN:
	case EXPR_RSHT_ASSIGN:
	case EXPR_ADD_ASSIGN:
	case EXPR_SUB_ASSIGN:
	case EXPR_COMMA:
	case EXPR_ARG:
		astValue = 0;
		break;
	}
	if( astLValue > 0 && ( astRValue > 0 || op == EXPR_CONDITION ) ){
		switch(op){
		case EXPR_MUL:
			astValue = CcCalMultiplicative( astLValue, astRValue, astType );
			break;
		case EXPR_DIV:
			astValue = CcCalDivision( astLValue, astRValue, astType );
			break;
		case EXPR_MOD:
			astValue = CcCalRemainder( astLValue, astRValue, astType );
			break;
		case EXPR_LEFTSHIFT:
			astValue = CcCalLeftShift( astLValue, astRValue );
			break;
		case EXPR_RIGHTSHIFT:
			astValue = CcCalRightShift( astLValue, astRValue );
			break;
		case EXPR_BIT_AND:
			astValue = CcCalBitAnd( astLValue, astRValue, astType );
			break;
		case EXPR_BIT_EXOR:
			astValue = CcCalBitExOr( astLValue, astRValue, astType );
			break;
		case EXPR_BIT_INOR:
			astValue = CcCalBitInOr( astLValue, astRValue, astType );
			break;
		case EXPR_ADD:
			astValue = CcCalAdditive( astLValue, astRValue, astType );
			break;
		case EXPR_SUB:
			astValue = CcCalSubtraction( astLValue, astRValue, astType );
			break;
		case EXPR_GREATER:
			astValue = CcCalSubtraction( astLValue, astRValue, astType );
			if( CcValueIsPositive( astValue ) ){
				astValue = CcValueGetOne( TYPE_INT );
			}else{
				astValue = CcValueGetZero( TYPE_INT );
			}
			break;
		case EXPR_GREATEREQU:
			astValue = CcCalSubtraction( astLValue, astRValue, astType );
			astValue = CcCalSubtraction( astLValue, astRValue, astType );
			if( CcValueIsPositive( astValue ) || CcValueIsZero( astValue ) ){
				astValue = CcValueGetOne( TYPE_INT );
			}else{
				astValue = CcValueGetZero( TYPE_INT );
			}
			break;
		case EXPR_LESS:
			astValue = CcCalSubtraction( astLValue, astRValue, astType );
			if( CcValueIsNegative( astValue ) ){
				astValue = CcValueGetOne( TYPE_INT );
			}else{
				astValue = CcValueGetZero( TYPE_INT );
			}
			break;
		case EXPR_LESSEQU:
			astValue = CcCalSubtraction( astLValue, astRValue, astType );
			if( CcValueIsNegative( astValue ) || CcValueIsZero( astValue ) ){
				astValue = CcValueGetOne( TYPE_INT );
			}else{
				astValue = CcValueGetZero( TYPE_INT );
			}
			break;
		case EXPR_EQUAL:
			astValue = CcCalSubtraction( astLValue, astRValue, astType );
			if( CcValueIsZero( astValue ) ){
				astValue = CcValueGetOne( TYPE_INT );
			}else{
				astValue = CcValueGetZero( TYPE_INT );
			}
			break;
		case EXPR_UNEQUAL:
			astValue = CcCalSubtraction( astLValue, astRValue, astType );
			if( CcValueIsZero( astValue ) ){
				astValue = CcValueGetZero ( TYPE_INT );
			}else{
				astValue = CcValueGetOne( TYPE_INT );
			}
			break;
		case EXPR_LOGIC_AND:
			if( CcValueIsZero( astLValue ) || CcValueIsZero( astRValue )  ){
				astValue = CcValueGetZero ( TYPE_INT );
			}else{
				astValue = CcValueGetOne( TYPE_INT );
			}
			break;
		case EXPR_LOGIC_OR:
			if( CcValueIsZero( astLValue ) && CcValueIsZero( astRValue )  ){
				astValue = CcValueGetZero ( TYPE_INT );
			}else{
				astValue = CcValueGetOne( TYPE_INT );
			}
			break;
		case EXPR_CONDITION:
			/*debug,13/1/29,S*/
			astRChild = stExpressionAccess.rightChild.get( astRoot );
			if( CcValueIsZero( astLValue )  ){
				astRChild = stExpressionAccess.rightChild.get( astRChild );
				astValue = stExpressionAccess.constValue.get( astRChild );
			}else{
				astLChild = stExpressionAccess.leftChild.get( astRChild );
				astValue = stExpressionAccess.constValue.get( astLChild );
			}
			break;
			/*debug,13/1/29,E*/
		case EXPR_COLON:
			astValue = 0;
			break;
		case EXPR_ASSIGN:
		case EXPR_MUL_ASSIGN:
		case EXPR_DIV_ASSIGN:
		case EXPR_MOD_ASSIGN:
		case EXPR_BITAND_ASSIGN:
		case EXPR_BITEXOR_ASSIGN:
		case EXPR_BITINOR_ASSIGN:
		case EXPR_LSHT_ASSIGN:
		case EXPR_RSHT_ASSIGN:
		case EXPR_ADD_ASSIGN:
		case EXPR_SUB_ASSIGN:
		case EXPR_COMMA:
		case EXPR_ARG:
			astValue = 0;
			break;
		}
	}
	if( astValue ){
		stExpressionAccess.constValue.set( astRoot, astValue );
	}
	return astValue;
}

AST  CcExpression( U4 *ulEndToken, U2 parentKind, AST astParent ){
	AST  astExp;
	BOOL bIllegal = FALSE;
	BOOL bRightType;
	S2  constFlg;

	astExp = ccExpParser(ulEndToken);
	if( astExp > 0 ){

		switch( parentKind ){
		case KIND_DECLARATOR:
			stExpressionAccess.parent_declarator.set( astExp, astParent );
			break;
		case KIND_EXPRESSIONINFO:
			stExpressionAccess.parent_expression.set( astExp, astParent );
			break;
		case KIND_STATEMENTINFO:
			stExpressionAccess.parent_statement.set( astExp, astParent );
			break;
		case KIND_INITDESIGNATION:
			stExpressionAccess.parent_designation.set( astExp, astParent );
			break;
		case KIND_INITIALEXPLIST:
			stExpressionAccess.parent_explist.set( astExp, astParent );
			break;
		}
		stExpressionAccess.parentKind.set( astExp, parentKind );
		bIllegal = ccExpCheckTree( astExp );
		if( !bIllegal ){
			bRightType = ccExpSolveTypes( astExp );
			if( bRightType ){
				ccExpSetFlag( astExp );
				constFlg = stExpressionAccess.constFlg.get( astExp );
				if(! ccExpIsFixedFlg(constFlg )){
					if( ccExpIsAddrConstFlg( constFlg ) ){
						constFlg = INIT_CONSTANT;
					}else{
						constFlg = NOT_CONSTANT;
					}
					stExpressionAccess.constFlg.set( astExp, constFlg );
				}

			}
		}else{
			CcThrowWarning( CC_EXP_FORMAT_ERROR,
					stExpressionAccess.codeScp.get( astExp ),
					NULL, NULL );
		}
	}
	return astExp;
}
AST  CcConstantExpression( U4 *ulEndToken, U2 parentKind, AST astParent ){
	AST  astExp;
	BOOL bIllegal = FALSE;
	BOOL bRightType;
	S2  constFlg;

	astExp = ccExpParser(ulEndToken);
	if( astExp > 0 ){

		switch( parentKind ){
		case KIND_DECLARATOR:
			stExpressionAccess.parent_declarator.set( astExp, astParent );
			break;
		case KIND_EXPRESSIONINFO:
			stExpressionAccess.parent_expression.set( astExp, astParent );
			break;
		case KIND_STATEMENTINFO:
			stExpressionAccess.parent_statement.set( astExp, astParent );
			break;
		case KIND_INITDESIGNATION:
			stExpressionAccess.parent_designation.set( astExp, astParent );
			break;
		case KIND_INITIALEXPLIST:
			stExpressionAccess.parent_explist.set( astExp, astParent );
			break;
		}
		stExpressionAccess.parentKind.set( astExp, parentKind );
		bIllegal = ccExpCheckTree( astExp );
		if( !bIllegal ){
			bRightType = ccExpSolveTypes( astExp );
			if( bRightType ){
				ccExpSetFlag( astExp );
				constFlg = stExpressionAccess.constFlg.get( astExp );
				if(! ccExpIsFixedFlg(constFlg )){
					if( ccExpIsAddrConstFlg( constFlg ) ){
						constFlg = INIT_CONSTANT;
					}else{
						constFlg = NOT_CONSTANT;
					}
					stExpressionAccess.constFlg.set( astExp, constFlg );
				}
			}
		}else{
			CcThrowWarning( CC_EXP_FORMAT_ERROR,
					stExpressionAccess.codeScp.get( astExp ),
					NULL, NULL );
		}
	}
	return astExp;
}
BOOL CcExprIsNullPointer( AST astNode ){
	return ccExprIsNullPointer( astNode );
}
